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.
@@ -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