jacktang-hacker-slides 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +21 -0
- data/README.textile +58 -0
- data/bin/hacker-slides +137 -0
- data/bundles/s5-simple.bundle +0 -0
- data/lib/hacker_slides.rb +2 -0
- data/lib/hacker_slides/bundle.rb +114 -0
- data/lib/hacker_slides/engine.rb +5 -0
- data/lib/hacker_slides/engine/base.rb +6 -0
- data/lib/hacker_slides/engine/markup_engine.rb +36 -0
- data/lib/hacker_slides/engine/render_engine.rb +12 -0
- data/lib/hacker_slides/engine/s5_slides_generator.rb +33 -0
- data/lib/hacker_slides/engine/slides_engine.rb +157 -0
- data/lib/hacker_slides/helper.rb +1 -0
- data/lib/hacker_slides/helper/content_helper.rb +46 -0
- data/lib/hacker_slides/presentation.rb +35 -0
- data/lib/hacker_slides/version.rb +13 -0
- data/lib/minitar.rb +124 -0
- data/lib/minitar/input.rb +149 -0
- data/lib/minitar/output.rb +206 -0
- data/lib/minitar/posix_header.rb +136 -0
- data/lib/minitar/reader.rb +199 -0
- data/lib/minitar/writer.rb +206 -0
- data/samples/sample.markdown +33 -0
- data/samples/sample.textile +29 -0
- metadata +104 -0
@@ -0,0 +1 @@
|
|
1
|
+
require 'hacker_slides/helper/content_helper'
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module HackerSlides
|
2
|
+
module ContentHelper
|
3
|
+
#
|
4
|
+
#
|
5
|
+
def slides_metadata
|
6
|
+
metadata_str = ''
|
7
|
+
metadata_str << "<title>#{@presentation.title}</title>\n"
|
8
|
+
metadata_str << "<!-- metadata -->\n"
|
9
|
+
metadata_str << "<meta name=\"author\" content=\"#{@presentation.author}\" />\n"
|
10
|
+
|
11
|
+
@presentation.meta.each do |name, value|
|
12
|
+
metadata_str << "<meta name=\"#{name}\" content=\"#{value}\" />\n"
|
13
|
+
end
|
14
|
+
metadata_str << "<meta name=\"generator\" content=\"HackerSlides\" />"
|
15
|
+
|
16
|
+
return metadata_str
|
17
|
+
end
|
18
|
+
|
19
|
+
#
|
20
|
+
#
|
21
|
+
def slides_footer
|
22
|
+
footer = <<EOF
|
23
|
+
<h1>#{@presentation.title}</h1>
|
24
|
+
<h2>Time:
|
25
|
+
<script type="text/javascript">
|
26
|
+
<!--
|
27
|
+
var currentTime = new Date()
|
28
|
+
var hours = currentTime.getHours()
|
29
|
+
var minutes = currentTime.getMinutes()
|
30
|
+
if (minutes < 10){
|
31
|
+
minutes = "0" + minutes
|
32
|
+
}
|
33
|
+
document.write(hours + ":" + minutes + " ")
|
34
|
+
if(hours > 11){
|
35
|
+
document.write("PM")
|
36
|
+
} else {
|
37
|
+
document.write("AM")
|
38
|
+
}
|
39
|
+
//-->
|
40
|
+
</script>
|
41
|
+
</h2>
|
42
|
+
EOF
|
43
|
+
return footer
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module HackerSlides
|
2
|
+
class Presentation
|
3
|
+
|
4
|
+
attr_accessor :title
|
5
|
+
attr_writer :author
|
6
|
+
attr_writer :version
|
7
|
+
attr_reader :created_at
|
8
|
+
attr_reader :meta
|
9
|
+
attr_reader :total_slides
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
@title = 'Untitled Presentation'
|
13
|
+
@meta = Hash.new
|
14
|
+
@meta[:created_at] = Time.now
|
15
|
+
@total_slides = 0
|
16
|
+
end
|
17
|
+
|
18
|
+
def author
|
19
|
+
return @meta[:author]
|
20
|
+
end
|
21
|
+
|
22
|
+
def version
|
23
|
+
return @meta[:version]
|
24
|
+
end
|
25
|
+
|
26
|
+
def created_at
|
27
|
+
return @meta[:created_at]
|
28
|
+
end
|
29
|
+
|
30
|
+
def incr_slides
|
31
|
+
@total_slides = @total_slides + 1
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
data/lib/minitar.rb
ADDED
@@ -0,0 +1,124 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#--
|
3
|
+
# Archive::Tar::Minitar 0.5.2
|
4
|
+
# Copyright 2004 Mauricio Julio Ferna'ndez Pradier and Austin Ziegler
|
5
|
+
#
|
6
|
+
# This program is based on and incorporates parts of RPA::Package from
|
7
|
+
# rpa-base (lib/rpa/package.rb and lib/rpa/util.rb) by Mauricio and has been
|
8
|
+
# adapted to be more generic by Austin.
|
9
|
+
#
|
10
|
+
# It is licensed under the GNU General Public Licence or Ruby's licence.
|
11
|
+
#
|
12
|
+
# $Id: minitar.rb 213 2008-02-26 22:32:11Z austin $
|
13
|
+
#++
|
14
|
+
require 'zlib'
|
15
|
+
require 'fileutils'
|
16
|
+
require 'find'
|
17
|
+
|
18
|
+
# = Archive::Tar::Minitar 0.5.2
|
19
|
+
# Archive::Tar::Minitar is a pure-Ruby library and command-line
|
20
|
+
# utility that provides the ability to deal with POSIX tar(1) archive
|
21
|
+
# files. The implementation is based heavily on Mauricio Ferna'ndez's
|
22
|
+
# implementation in rpa-base, but has been reorganised to promote
|
23
|
+
# reuse in other projects.
|
24
|
+
#
|
25
|
+
# This tar class performs a subset of all tar (POSIX tape archive)
|
26
|
+
# operations. We can only deal with typeflags 0, 1, 2, and 5 (see
|
27
|
+
# Archive::Tar::PosixHeader). All other typeflags will be treated as
|
28
|
+
# normal files.
|
29
|
+
#
|
30
|
+
# NOTE::: support for typeflags 1 and 2 is not yet implemented in this
|
31
|
+
# version.
|
32
|
+
#
|
33
|
+
# This release is version 0.5.2. The library can only handle files and
|
34
|
+
# directories at this point. A future version will be expanded to
|
35
|
+
# handle symbolic links and hard links in a portable manner. The
|
36
|
+
# command line utility, minitar, can only create archives, extract
|
37
|
+
# from archives, and list archive contents.
|
38
|
+
#
|
39
|
+
# == Synopsis
|
40
|
+
# Using this library is easy. The simplest case is:
|
41
|
+
#
|
42
|
+
# require 'zlib'
|
43
|
+
# require 'archive/tar/minitar'
|
44
|
+
# include Archive::Tar
|
45
|
+
#
|
46
|
+
# # Packs everything that matches Find.find('tests')
|
47
|
+
# File.open('test.tar', 'wb') { |tar| Minitar.pack('tests', tar) }
|
48
|
+
# # Unpacks 'test.tar' to 'x', creating 'x' if necessary.
|
49
|
+
# Minitar.unpack('test.tar', 'x')
|
50
|
+
#
|
51
|
+
# A gzipped tar can be written with:
|
52
|
+
#
|
53
|
+
# tgz = Zlib::GzipWriter.new(File.open('test.tgz', 'wb'))
|
54
|
+
# # Warning: tgz will be closed!
|
55
|
+
# Minitar.pack('tests', tgz)
|
56
|
+
#
|
57
|
+
# tgz = Zlib::GzipReader.new(File.open('test.tgz', 'rb'))
|
58
|
+
# # Warning: tgz will be closed!
|
59
|
+
# Minitar.unpack(tgz, 'x')
|
60
|
+
#
|
61
|
+
# As the case above shows, one need not write to a file. However, it
|
62
|
+
# will sometimes require that one dive a little deeper into the API,
|
63
|
+
# as in the case of StringIO objects. Note that I'm not providing a
|
64
|
+
# block with Minitar::Output, as Minitar::Output#close automatically
|
65
|
+
# closes both the Output object and the wrapped data stream object.
|
66
|
+
#
|
67
|
+
# begin
|
68
|
+
# sgz = Zlib::GzipWriter.new(StringIO.new(""))
|
69
|
+
# tar = Output.new(sgz)
|
70
|
+
# Find.find('tests') do |entry|
|
71
|
+
# Minitar.pack_file(entry, tar)
|
72
|
+
# end
|
73
|
+
# ensure
|
74
|
+
# # Closes both tar and sgz.
|
75
|
+
# tar.close
|
76
|
+
# end
|
77
|
+
#
|
78
|
+
# == Copyright
|
79
|
+
# Copyright 2004 Mauricio Julio Ferna'ndez Pradier and Austin Ziegler
|
80
|
+
#
|
81
|
+
# This program is based on and incorporates parts of RPA::Package from
|
82
|
+
# rpa-base (lib/rpa/package.rb and lib/rpa/util.rb) by Mauricio and
|
83
|
+
# has been adapted to be more generic by Austin.
|
84
|
+
#
|
85
|
+
# 'minitar' contains an adaptation of Ruby/ProgressBar by Satoru
|
86
|
+
# Takabayashi <satoru@namazu.org>, copyright 2001 - 2004.
|
87
|
+
#
|
88
|
+
# This program is free software. It may be redistributed and/or
|
89
|
+
# modified under the terms of the GPL version 2 (or later) or Ruby's
|
90
|
+
# licence.
|
91
|
+
module Archive
|
92
|
+
module Tar
|
93
|
+
module Minitar
|
94
|
+
|
95
|
+
VERSION = "0.5.2"
|
96
|
+
|
97
|
+
# The exception raised when a wrapped data stream class is expected to
|
98
|
+
# respond to #rewind or #pos but does not.
|
99
|
+
class NonSeekableStream < StandardError; end
|
100
|
+
# The exception raised when a block is required for proper operation of
|
101
|
+
# the method.
|
102
|
+
class BlockRequired < ArgumentError; end
|
103
|
+
# The exception raised when operations are performed on a stream that has
|
104
|
+
# previously been closed.
|
105
|
+
class ClosedStream < StandardError; end
|
106
|
+
# The exception raised when a filename exceeds 256 bytes in length,
|
107
|
+
# the maximum supported by the standard Tar format.
|
108
|
+
class FileNameTooLong < StandardError; end
|
109
|
+
# The exception raised when a data stream ends before the amount of data
|
110
|
+
# expected in the archive's PosixHeader.
|
111
|
+
class UnexpectedEOF < StandardError; end
|
112
|
+
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
require 'minitar/posix_header'
|
119
|
+
require 'minitar/writer'
|
120
|
+
require 'minitar/reader'
|
121
|
+
require 'minitar/input'
|
122
|
+
require 'minitar/output'
|
123
|
+
|
124
|
+
|
@@ -0,0 +1,149 @@
|
|
1
|
+
module Archive
|
2
|
+
module Tar
|
3
|
+
module Minitar
|
4
|
+
|
5
|
+
# Wraps a Archive::Tar::Minitar::Reader with convenience methods and
|
6
|
+
# wrapped stream management; Input only works with random access data
|
7
|
+
# streams. See Input::new for details.
|
8
|
+
class Input
|
9
|
+
include Enumerable
|
10
|
+
|
11
|
+
# With no associated block, +Input::open+ is a synonym for
|
12
|
+
# +Input::new+. If the optional code block is given, it will be passed
|
13
|
+
# the new _writer_ as an argument and the Input object will
|
14
|
+
# automatically be closed when the block terminates. In this instance,
|
15
|
+
# +Input::open+ returns the value of the block.
|
16
|
+
def self.open(input)
|
17
|
+
stream = Input.new(input)
|
18
|
+
return stream unless block_given?
|
19
|
+
|
20
|
+
begin
|
21
|
+
res = yield stream
|
22
|
+
ensure
|
23
|
+
stream.close
|
24
|
+
end
|
25
|
+
|
26
|
+
res
|
27
|
+
end
|
28
|
+
|
29
|
+
# Creates a new Input object. If +input+ is a stream object that responds
|
30
|
+
# to #read), then it will simply be wrapped. Otherwise, one will be
|
31
|
+
# created and opened using Kernel#open. When Input#close is called, the
|
32
|
+
# stream object wrapped will be closed.
|
33
|
+
def initialize(input)
|
34
|
+
if input.respond_to?(:read)
|
35
|
+
@io = input
|
36
|
+
else
|
37
|
+
@io = open(input, "rb")
|
38
|
+
end
|
39
|
+
@tarreader = Archive::Tar::Minitar::Reader.new(@io)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Iterates through each entry and rewinds to the beginning of the stream
|
43
|
+
# when finished.
|
44
|
+
def each(&block)
|
45
|
+
@tarreader.each { |entry| yield entry }
|
46
|
+
ensure
|
47
|
+
@tarreader.rewind
|
48
|
+
end
|
49
|
+
|
50
|
+
# Extracts the current +entry+ to +destdir+. If a block is provided, it
|
51
|
+
# yields an +action+ Symbol, the full name of the file being extracted
|
52
|
+
# (+name+), and a Hash of statistical information (+stats+).
|
53
|
+
#
|
54
|
+
# The +action+ will be one of:
|
55
|
+
# <tt>:dir</tt>:: The +entry+ is a directory.
|
56
|
+
# <tt>:file_start</tt>:: The +entry+ is a file; the extract of the
|
57
|
+
# file is just beginning.
|
58
|
+
# <tt>:file_progress</tt>:: Yielded every 4096 bytes during the extract
|
59
|
+
# of the +entry+.
|
60
|
+
# <tt>:file_done</tt>:: Yielded when the +entry+ is completed.
|
61
|
+
#
|
62
|
+
# The +stats+ hash contains the following keys:
|
63
|
+
# <tt>:current</tt>:: The current total number of bytes read in the
|
64
|
+
# +entry+.
|
65
|
+
# <tt>:currinc</tt>:: The current number of bytes read in this read
|
66
|
+
# cycle.
|
67
|
+
# <tt>:entry</tt>:: The entry being extracted; this is a
|
68
|
+
# Reader::EntryStream, with all methods thereof.
|
69
|
+
def extract_entry(destdir, entry) # :yields action, name, stats:
|
70
|
+
stats = {
|
71
|
+
:current => 0,
|
72
|
+
:currinc => 0,
|
73
|
+
:entry => entry
|
74
|
+
}
|
75
|
+
|
76
|
+
if entry.directory?
|
77
|
+
dest = File.join(destdir, entry.full_name)
|
78
|
+
|
79
|
+
yield :dir, entry.full_name, stats if block_given?
|
80
|
+
|
81
|
+
if Archive::Tar::Minitar.dir?(dest)
|
82
|
+
begin
|
83
|
+
FileUtils.chmod(entry.mode, dest)
|
84
|
+
rescue Exception
|
85
|
+
nil
|
86
|
+
end
|
87
|
+
else
|
88
|
+
FileUtils.mkdir_p(dest, :mode => entry.mode)
|
89
|
+
FileUtils.chmod(entry.mode, dest)
|
90
|
+
end
|
91
|
+
|
92
|
+
fsync_dir(dest)
|
93
|
+
fsync_dir(File.join(dest, ".."))
|
94
|
+
return
|
95
|
+
else # it's a file
|
96
|
+
destdir = File.join(destdir, File.dirname(entry.full_name))
|
97
|
+
FileUtils.mkdir_p(destdir, :mode => 0755)
|
98
|
+
|
99
|
+
destfile = File.join(destdir, File.basename(entry.full_name))
|
100
|
+
FileUtils.chmod(0600, destfile) rescue nil # Errno::ENOENT
|
101
|
+
|
102
|
+
yield :file_start, entry.full_name, stats if block_given?
|
103
|
+
|
104
|
+
File.open(destfile, "wb", entry.mode) do |os|
|
105
|
+
loop do
|
106
|
+
data = entry.read(4096)
|
107
|
+
break unless data
|
108
|
+
|
109
|
+
stats[:currinc] = os.write(data)
|
110
|
+
stats[:current] += stats[:currinc]
|
111
|
+
|
112
|
+
yield :file_progress, entry.full_name, stats if block_given?
|
113
|
+
end
|
114
|
+
os.fsync
|
115
|
+
end
|
116
|
+
|
117
|
+
FileUtils.chmod(entry.mode, destfile)
|
118
|
+
fsync_dir(File.dirname(destfile))
|
119
|
+
fsync_dir(File.join(File.dirname(destfile), ".."))
|
120
|
+
|
121
|
+
yield :file_done, entry.full_name, stats if block_given?
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
# Returns the Reader object for direct access.
|
126
|
+
def tar
|
127
|
+
@tarreader
|
128
|
+
end
|
129
|
+
|
130
|
+
# Closes the Reader object and the wrapped data stream.
|
131
|
+
def close
|
132
|
+
@io.close
|
133
|
+
@tarreader.close
|
134
|
+
end
|
135
|
+
|
136
|
+
private
|
137
|
+
def fsync_dir(dirname)
|
138
|
+
# make sure this hits the disc
|
139
|
+
dir = open(dirname, 'rb')
|
140
|
+
dir.fsync
|
141
|
+
rescue # ignore IOError if it's an unpatched (old) Ruby
|
142
|
+
nil
|
143
|
+
ensure
|
144
|
+
dir.close if dir rescue nil
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
@@ -0,0 +1,206 @@
|
|
1
|
+
module Archive
|
2
|
+
module Tar
|
3
|
+
module Minitar
|
4
|
+
|
5
|
+
# Wraps a Archive::Tar::Minitar::Writer with convenience methods and
|
6
|
+
# wrapped stream management; Output only works with random access data
|
7
|
+
# streams. See Output::new for details.
|
8
|
+
class Output
|
9
|
+
# With no associated block, +Output::open+ is a synonym for
|
10
|
+
# +Output::new+. If the optional code block is given, it will be passed
|
11
|
+
# the new _writer_ as an argument and the Output object will
|
12
|
+
# automatically be closed when the block terminates. In this instance,
|
13
|
+
# +Output::open+ returns the value of the block.
|
14
|
+
def self.open(output)
|
15
|
+
stream = Output.new(output)
|
16
|
+
return stream unless block_given?
|
17
|
+
|
18
|
+
begin
|
19
|
+
res = yield stream
|
20
|
+
ensure
|
21
|
+
stream.close
|
22
|
+
end
|
23
|
+
|
24
|
+
res
|
25
|
+
end
|
26
|
+
|
27
|
+
# Creates a new Output object. If +output+ is a stream object that
|
28
|
+
# responds to #read), then it will simply be wrapped. Otherwise, one will
|
29
|
+
# be created and opened using Kernel#open. When Output#close is called,
|
30
|
+
# the stream object wrapped will be closed.
|
31
|
+
def initialize(output)
|
32
|
+
if output.respond_to?(:write)
|
33
|
+
@io = output
|
34
|
+
else
|
35
|
+
@io = ::File.open(output, "wb")
|
36
|
+
end
|
37
|
+
@tarwriter = Archive::Tar::Minitar::Writer.new(@io)
|
38
|
+
end
|
39
|
+
|
40
|
+
# Returns the Writer object for direct access.
|
41
|
+
def tar
|
42
|
+
@tarwriter
|
43
|
+
end
|
44
|
+
|
45
|
+
# Closes the Writer object and the wrapped data stream.
|
46
|
+
def close
|
47
|
+
@tarwriter.close
|
48
|
+
@io.close
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
class << self
|
53
|
+
# Tests if +path+ refers to a directory. Fixes an apparently
|
54
|
+
# corrupted <tt>stat()</tt> call on Windows.
|
55
|
+
def dir?(path)
|
56
|
+
File.directory?((path[-1] == '/') ? path : "#{path}/")
|
57
|
+
end
|
58
|
+
|
59
|
+
# A convenience method for wrapping Archive::Tar::Minitar::Input.open
|
60
|
+
# (mode +r+) and Archive::Tar::Minitar::Output.open (mode +w+). No other
|
61
|
+
# modes are currently supported.
|
62
|
+
def open(dest, mode = "r", &block)
|
63
|
+
case mode
|
64
|
+
when "r"
|
65
|
+
Input.open(dest, &block)
|
66
|
+
when "w"
|
67
|
+
Output.open(dest, &block)
|
68
|
+
else
|
69
|
+
raise "Unknown open mode for Archive::Tar::Minitar.open."
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# A convenience method to packs the file provided. +entry+ may either be
|
74
|
+
# a filename (in which case various values for the file (see below) will
|
75
|
+
# be obtained from <tt>File#stat(entry)</tt> or a Hash with the fields:
|
76
|
+
#
|
77
|
+
# <tt>:name</tt>:: The filename to be packed into the tarchive.
|
78
|
+
# *REQUIRED*.
|
79
|
+
# <tt>:mode</tt>:: The mode to be applied.
|
80
|
+
# <tt>:uid</tt>:: The user owner of the file. (Ignored on Windows.)
|
81
|
+
# <tt>:gid</tt>:: The group owner of the file. (Ignored on Windows.)
|
82
|
+
# <tt>:mtime</tt>:: The modification Time of the file.
|
83
|
+
#
|
84
|
+
# During packing, if a block is provided, #pack_file yields an +action+
|
85
|
+
# Symol, the full name of the file being packed, and a Hash of
|
86
|
+
# statistical information, just as with
|
87
|
+
# Archive::Tar::Minitar::Input#extract_entry.
|
88
|
+
#
|
89
|
+
# The +action+ will be one of:
|
90
|
+
# <tt>:dir</tt>:: The +entry+ is a directory.
|
91
|
+
# <tt>:file_start</tt>:: The +entry+ is a file; the extract of the
|
92
|
+
# file is just beginning.
|
93
|
+
# <tt>:file_progress</tt>:: Yielded every 4096 bytes during the extract
|
94
|
+
# of the +entry+.
|
95
|
+
# <tt>:file_done</tt>:: Yielded when the +entry+ is completed.
|
96
|
+
#
|
97
|
+
# The +stats+ hash contains the following keys:
|
98
|
+
# <tt>:current</tt>:: The current total number of bytes read in the
|
99
|
+
# +entry+.
|
100
|
+
# <tt>:currinc</tt>:: The current number of bytes read in this read
|
101
|
+
# cycle.
|
102
|
+
# <tt>:name</tt>:: The filename to be packed into the tarchive.
|
103
|
+
# *REQUIRED*.
|
104
|
+
# <tt>:mode</tt>:: The mode to be applied.
|
105
|
+
# <tt>:uid</tt>:: The user owner of the file. (+nil+ on Windows.)
|
106
|
+
# <tt>:gid</tt>:: The group owner of the file. (+nil+ on Windows.)
|
107
|
+
# <tt>:mtime</tt>:: The modification Time of the file.
|
108
|
+
def pack_file(entry, outputter) #:yields action, name, stats:
|
109
|
+
outputter = outputter.tar if outputter.kind_of?(Archive::Tar::Minitar::Output)
|
110
|
+
|
111
|
+
stats = {}
|
112
|
+
|
113
|
+
if entry.kind_of?(Hash)
|
114
|
+
name = entry[:name]
|
115
|
+
|
116
|
+
entry.each { |kk, vv| stats[kk] = vv unless vv.nil? }
|
117
|
+
else
|
118
|
+
name = entry
|
119
|
+
end
|
120
|
+
|
121
|
+
name = name.sub(%r{\./}, '')
|
122
|
+
stat = File.stat(name)
|
123
|
+
stats[:mode] ||= stat.mode
|
124
|
+
stats[:mtime] ||= stat.mtime
|
125
|
+
stats[:size] = stat.size
|
126
|
+
|
127
|
+
if RUBY_PLATFORM =~ /win32/
|
128
|
+
stats[:uid] = nil
|
129
|
+
stats[:gid] = nil
|
130
|
+
else
|
131
|
+
stats[:uid] ||= stat.uid
|
132
|
+
stats[:gid] ||= stat.gid
|
133
|
+
end
|
134
|
+
|
135
|
+
case
|
136
|
+
when File.file?(name)
|
137
|
+
outputter.add_file_simple(name, stats) do |os|
|
138
|
+
stats[:current] = 0
|
139
|
+
yield :file_start, name, stats if block_given?
|
140
|
+
File.open(name, "rb") do |ff|
|
141
|
+
until ff.eof?
|
142
|
+
stats[:currinc] = os.write(ff.read(4096))
|
143
|
+
stats[:current] += stats[:currinc]
|
144
|
+
yield :file_progress, name, stats if block_given?
|
145
|
+
end
|
146
|
+
end
|
147
|
+
yield :file_done, name, stats if block_given?
|
148
|
+
end
|
149
|
+
when dir?(name)
|
150
|
+
yield :dir, name, stats if block_given?
|
151
|
+
outputter.mkdir(name, stats)
|
152
|
+
else
|
153
|
+
raise "Don't yet know how to pack this type of file."
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
# A convenience method to pack files specified by +src+ into +dest+. If
|
158
|
+
# +src+ is an Array, then each file detailed therein will be packed into
|
159
|
+
# the resulting Archive::Tar::Minitar::Output stream; if +recurse_dirs+
|
160
|
+
# is true, then directories will be recursed.
|
161
|
+
#
|
162
|
+
# If +src+ is an Array, it will be treated as the argument to Find.find;
|
163
|
+
# all files matching will be packed.
|
164
|
+
def pack(src, dest, recurse_dirs = true, &block)
|
165
|
+
Output.open(dest) do |outp|
|
166
|
+
if src.kind_of?(Array)
|
167
|
+
src.each do |entry|
|
168
|
+
pack_file(entry, outp, &block)
|
169
|
+
if dir?(entry) and recurse_dirs
|
170
|
+
Dir["#{entry}/**/**"].each do |ee|
|
171
|
+
pack_file(ee, outp, &block)
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
else
|
176
|
+
Find.find(src) do |entry|
|
177
|
+
pack_file(entry, outp, &block)
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
# A convenience method to unpack files from +src+ into the directory
|
184
|
+
# specified by +dest+. Only those files named explicitly in +files+
|
185
|
+
# will be extracted.
|
186
|
+
def unpack(src, dest, files = [], &block)
|
187
|
+
Input.open(src) do |inp|
|
188
|
+
if File.exist?(dest) and (not dir?(dest))
|
189
|
+
raise "Can't unpack to a non-directory."
|
190
|
+
elsif not File.exist?(dest)
|
191
|
+
FileUtils.mkdir_p(dest)
|
192
|
+
end
|
193
|
+
|
194
|
+
inp.each do |entry|
|
195
|
+
if files.empty? or files.include?(entry.full_name)
|
196
|
+
inp.extract_entry(dest, entry, &block)
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
end
|
203
|
+
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|