jacktang-hacker-slides 1.0.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/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
|