jacktang-hacker-slides 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -0,0 +1,13 @@
1
+ module HackerSlides
2
+ class Version
3
+ MAIN = 1
4
+ MAJOR = 0
5
+ MINOR = 1
6
+
7
+ class << self
8
+ def value
9
+ return "#{MAIN}.#{MAJOR}.#{MINOR}"
10
+ end
11
+ end
12
+ end
13
+ 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