woody 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in podgen.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 David Robertson
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,21 @@
1
+ # Woody
2
+
3
+ Podcast static site generator
4
+
5
+ ## Installation
6
+
7
+ To install, run this:
8
+
9
+ $ gem install woody
10
+
11
+ ## Usage
12
+
13
+ TODO: Write usage instructions here
14
+
15
+ ## Contributing
16
+
17
+ 1. Fork it
18
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
19
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
20
+ 4. Push to the branch (`git push origin my-new-feature`)
21
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/bin/woody ADDED
@@ -0,0 +1,58 @@
1
+ #! /usr/bin/env ruby
2
+
3
+ require 'woody'
4
+ require 'commander/import'
5
+
6
+ puts
7
+ puts
8
+ puts
9
+
10
+ program :name, 'woody'
11
+ program :version, Woody::VERSION
12
+ program :description, 'Podcast static site generator'
13
+
14
+
15
+ command :compile do |c|
16
+ c.description = "Compiles the site"
17
+ c.action do |args, options|
18
+ Woody.init
19
+ Woody.compile
20
+ end
21
+ end
22
+
23
+ command :deploy do |c|
24
+ c.description = "Deploys the site"
25
+ c.action do |args, options|
26
+ Woody.init
27
+ Woody.deploy
28
+ end
29
+ end
30
+
31
+ command :cd do |c|
32
+ c.description = "Compiles then deploys the site"
33
+ c.action do |args, options|
34
+ Woody.init
35
+ Woody.compile
36
+ Woody.deploy
37
+ end
38
+ end
39
+
40
+ command :new do |c|
41
+ c.description = "Creates a blank Woody site with some defaults"
42
+ c.syntax = "new [sitename]"
43
+ c.action do |args, options|
44
+ if args[0].nil? or !(args[0].is_a? String)
45
+ puts "Syntax: woody new [sitename]"
46
+ exit!
47
+ end
48
+ Woody::new_site(args[0])
49
+ end
50
+ end
51
+
52
+ command :update_templates do |c|
53
+ c.description = "Sets template files to current default. DESTRUCTIVE!"
54
+ c.action do |args, options|
55
+ Woody.init
56
+ Woody::update_templates
57
+ end
58
+ end
@@ -0,0 +1,3 @@
1
+ module Woody
2
+ VERSION = "0.0.7"
3
+ end
data/lib/woody.rb ADDED
@@ -0,0 +1,306 @@
1
+ require "woody/version"
2
+
3
+ require 'yaml'
4
+ require 'erubis'
5
+ require 'mp3info'
6
+ require 'aws/s3'
7
+ require 'digest'
8
+ require 'fileutils'
9
+
10
+
11
+ module Woody
12
+ $source_root = File.expand_path("../../templates", __FILE__)
13
+
14
+ # Load configuration
15
+ def self.init
16
+ begin
17
+ $config = YAML.load_file("woody-config.yml")
18
+ rescue Errno::ENOENT
19
+ puts "This doesn't look like a valid Woody site directory!"
20
+ return
21
+ end
22
+
23
+ AWS::S3::Base.establish_connection!(
24
+ :access_key_id => $config['s3']['accesskey']['id'],
25
+ :secret_access_key => $config['s3']['accesskey']['secret']
26
+ )
27
+ AWS::S3::DEFAULT_HOST.replace $config['s3']['hostname']
28
+ $bucketname = $config['s3']['bucket']
29
+ $itunes_image_url = "FILL IN URL"
30
+ end
31
+
32
+ def self.new_site(name)
33
+ puts "Creating new site '#{name}'..."
34
+ if File.directory?(name)
35
+ puts "Error: directory '#{name}' already exists!"
36
+ return false
37
+ end
38
+
39
+ cdir_p(name)
40
+ cpy_t("woody-config.yml", "#{name}/woody-config.yml")
41
+
42
+ cdir_p("#{name}/templates")
43
+ cpy_t("layout.html", "#{name}/templates/layout.html")
44
+ cpy_t("index.html", "#{name}/templates/index.html")
45
+ cpy_t("episode.html", "#{name}/templates/episode.html")
46
+
47
+ cdir_p("#{name}/templates/assets")
48
+ cpy_t("stylesheet.css", "#{name}/templates/assets/stylesheet.css")
49
+
50
+ cdir_p("#{name}/content")
51
+ cpy_t("metadata.yml", "#{name}/content/metadata.yml")
52
+
53
+
54
+ cdir_p("#{name}/output")
55
+ cdir_p("#{name}/output/assets")
56
+ cdir_p("#{name}/output/assets/mp3")
57
+ cdir_p("#{name}/output/episode")
58
+
59
+ puts "Done!"
60
+ puts "Now, do `cd #{name}` then edit the config file, woody-config.yml."
61
+ end
62
+
63
+ def self.update_templates
64
+ puts "Updating templates..."
65
+ cpy_t("layout.html", "templates/layout.html")
66
+ cpy_t("index.html", "templates/index.html")
67
+ cpy_t("episode.html", "templates/episode.html")
68
+ cpy_t("stylesheet.css", "templates/assets/stylesheet.css")
69
+ puts "Done! Thanks for updating :)"
70
+ end
71
+
72
+ def self.cdir_p(dir)
73
+ puts "Creating directory '#{dir}'"
74
+ FileUtils.mkdir_p(dir)
75
+ end
76
+ def self.cpy_t(source, destination)
77
+ puts "Creating file '#{destination}'"
78
+ FileUtils.cp File.join($source_root, source), destination
79
+ end
80
+
81
+ class Episode
82
+ def self.new_from_meta(filename, meta)
83
+ return Episode.new(filename, meta['title'], Date.parse(meta['date']), meta['synopsis'], meta['subtitle'], meta['tags'])
84
+ end
85
+ def initialize(filename, title, date, synopsis, subtitle = nil, tags = [], compiledname = nil)
86
+ @filename = filename
87
+ @title = title
88
+ @date = date
89
+ @synopsis = synopsis
90
+ @subtitle = subtitle
91
+ @tags = tags
92
+ @compiledname = compiledname
93
+
94
+ if @compiledname.nil? or @compiledname.empty?
95
+ @compiledname = @filename.gsub(/[^0-9A-Za-z .]/, '').gsub(' ','_')
96
+ end
97
+ end
98
+ attr_accessor :filename, :title, :date, :synopsis, :tags, :subtitle, :compiledname
99
+ def duration
100
+ return @duration unless @duration.nil?
101
+ length = 0
102
+ Mp3Info.open("content/#{@filename}") do |mp3|
103
+ length = mp3.length
104
+ end
105
+ length = length.to_i
106
+ seconds = length % 60
107
+ minutes = (length / 60).to_i
108
+ @duration = "#{minutes}:#{seconds}"
109
+ end
110
+ def size
111
+ File.size "content/#{filename}"
112
+ end
113
+ def keywords
114
+ @tags.join ', ' unless @tags.nil? or @tags.empty?
115
+ end
116
+ def file_path(leader=true)
117
+ return "#{leader ? "/" : ""}assets/mp3/#{@compiledname}" unless @compiledname.nil?
118
+ return false
119
+ end
120
+ def file_url
121
+ return "#{$config['urlbase']}#{file_path}" unless file_path.nil?
122
+ return false
123
+ end
124
+ def path(leader=true)
125
+ return "#{leader ? "/" : ""}episode/#{@compiledname[0..-5]}.html" unless @compiledname.nil?
126
+ return false
127
+ end
128
+ def url
129
+ return "#{$config['urlbase']}#{path}" unless path.nil?
130
+ return false
131
+ end
132
+ end
133
+
134
+ def self.compile()
135
+ puts "Compiling..."
136
+ meta = YAML.load_file("content/metadata.yml")
137
+
138
+ episodes = Array.new
139
+ filesfound = Array.new
140
+ touchedfiles = Array.new
141
+ Dir.glob('content/*.mp3') do |file|
142
+ filename = file[8..-1]
143
+ unless meta == false or meta[filename].nil?
144
+ # Episode metadata already stored
145
+ episodes << Episode.new_from_meta(filename, meta[filename])
146
+ filesfound << filename
147
+ else
148
+ # No episode metadata stored for this yet
149
+
150
+ puts "Warning: no metadata found for file #{filename}"
151
+ end
152
+ end
153
+
154
+ # Check for files in meta but not found
155
+ unless meta == false
156
+ meta.each do |file|
157
+ next if filesfound.include? file[0]
158
+ puts "Warning: found metadata for file #{file[0]}, but file itself is missing. Will not be published."
159
+ end
160
+ end
161
+
162
+ # Make sure necessary directories exist
163
+ FileUtils.mkdir_p('output/assets') unless File.directory?('output/assets')
164
+ FileUtils.mkdir_p('output/assets/mp3') unless File.directory?('output/assets/mp3')
165
+ FileUtils.mkdir_p('output/episode') unless File.directory?('output/episode')
166
+
167
+ # Copy over (TODO: and process) MP3 files
168
+ episodes.each do |episode|
169
+ FileUtils.copy "content/#{episode.filename}", "output/assets/mp3/#{episode.compiledname}"
170
+ touchedfiles << "assets/mp3/#{episode.compiledname}"
171
+ end
172
+
173
+ # Copy over assets
174
+ Dir.foreach("templates/assets") do |item|
175
+ next if item == '.' or item == '..'
176
+ begin
177
+ FileUtils.copy "templates/assets/#{item}", "output/assets/#{item}"
178
+ touchedfiles << "assets/#{item}"
179
+ rescue Errno::EISDIR
180
+ puts "Warning: subdirectories in templates/assets are ignored!"
181
+ end
182
+ end
183
+
184
+ # Update index.html
185
+ layout = File.read('templates/layout.html')
186
+ layout = Erubis::Eruby.new(layout)
187
+
188
+ index_compiled = layout.result(config: $config, episodes: episodes) do
189
+ index = Erubis::Eruby.new(File.read('templates/index.html'))
190
+ index.result(config: $config, episodes: episodes, test: "hello, world") do |episode|
191
+ ep = Erubis::Eruby.new(File.read('templates/episode.html'))
192
+ ep.result(config: $config, episodes: episodes, episode: episode)
193
+ end
194
+ end
195
+ File.open('output/index.html', 'w') {|f| f.write(index_compiled) }
196
+ touchedfiles << 'index.html'
197
+
198
+ # Update episode pages
199
+ episodes.each do |episode|
200
+ layout = File.read('templates/layout.html')
201
+ layout = Erubis::Eruby.new(layout)
202
+ episode_compiled = layout.result(config: $config, episodes: episodes) do
203
+ ep = Erubis::Eruby.new(File.read('templates/episode.html'))
204
+ ep.result(config: $config, episodes: episodes, episode: episode)
205
+ end
206
+ File.open("output/#{episode.path(false)}", 'w') {|f| f.write(episode_compiled) }
207
+ touchedfiles << episode.path(false)
208
+ end
209
+
210
+ # Update iTunes RSS
211
+ itunes = File.read "#{$source_root}/itunes.xml" # Use itunes.xml template in gem, not in site's template folder.
212
+ itunes = Erubis::Eruby.new(itunes)
213
+ itunes_compiled = itunes.result(config: $config, episodes: episodes)
214
+ File.open("output/itunes.xml", 'w') {|f| f.write(itunes_compiled) }
215
+ touchedfiles << "itunes.xml"
216
+
217
+
218
+ # Update General RSS
219
+
220
+
221
+ # Purge left over files
222
+ purge_output(touchedfiles)
223
+ end
224
+
225
+ def self.purge_output(touchedfiles, subdir = "")
226
+ Dir.foreach("output/#{subdir}") do |item|
227
+ next if item == '.' or item == '..'
228
+ p = "#{subdir}#{item}"
229
+ begin
230
+ File.delete "output/#{subdir}#{item}" unless touchedfiles.include? p
231
+ rescue Errno::EISDIR, Errno::EPERM # Rescuing EPERM seems to be necessary on macs, hmm :/
232
+ purge_output touchedfiles, "#{p}/"
233
+ end
234
+ end
235
+ end
236
+
237
+ def self.deploy
238
+ touchedfiles = Array.new
239
+ deploy_r touchedfiles
240
+
241
+ # Purge left over files
242
+ purge_bucket touchedfiles
243
+ end
244
+
245
+ def self.deploy_r(touchedfiles, subdir = "")
246
+ puts "Deploying... " if subdir == ""
247
+ Dir.foreach("output/#{subdir}") do |item|
248
+ next if item == '.' or item == '..'
249
+ begin
250
+ touchedfiles << "#{subdir}#{item}"
251
+ upload("#{subdir}#{item}", "output/#{subdir}#{item}")
252
+ rescue Errno::EISDIR
253
+ deploy_r touchedfiles, "#{subdir}#{item}/"
254
+ end
255
+ end
256
+ end
257
+
258
+ def self.purge_bucket(touchedfiles)
259
+ bucket = AWS::S3::Bucket.find $bucketname
260
+ bucket.objects.each do |object|
261
+ object.delete unless touchedfiles.include? object.key
262
+ end
263
+ end
264
+
265
+ def self.filehash(filepath)
266
+ sha1 = Digest::SHA1.new
267
+ File.open(filepath) do|file|
268
+ buffer = ''
269
+ # Read the file 512 bytes at a time
270
+ while not file.eof
271
+ file.read(512, buffer)
272
+ sha1.update(buffer)
273
+ end
274
+ end
275
+ return sha1.to_s
276
+ end
277
+
278
+ def self.upload(objectname, filepath)
279
+ # Generate hash of file
280
+ hash = filehash filepath
281
+
282
+ # Get hash of version already uploaded, if available.
283
+ begin
284
+ object = AWS::S3::S3Object.find objectname, $bucketname
285
+ oldhash = object.metadata['hash']
286
+ rescue AWS::S3::NoSuchKey
287
+ # File not uploaded yet
288
+ oldhash = nil
289
+ end
290
+ unless hash == oldhash
291
+ # Don't reupload if file hasn't changed
292
+ puts "#{objectname}: Uploading"
293
+ AWS::S3::S3Object.store(objectname, open(filepath), $bucketname, access: :public_read, 'x-amz-meta-hash' => hash)
294
+ else
295
+ puts "#{objectname}: Not uploading, hasn't changed since last time."
296
+ end
297
+ end
298
+
299
+
300
+
301
+
302
+ end
303
+
304
+ def link_to(name, url)
305
+ return %Q{<a href="#{url}">#{name}</a>}
306
+ end
@@ -0,0 +1,16 @@
1
+ <h3><%= link_to episode.title, episode.path %></h3>
2
+ <h4><%= episode.subtitle %></h4>
3
+ Player goes here
4
+
5
+ <a href="<%= episode.file_path %>">Download MP3</a>
6
+
7
+ <div class="synopsis">
8
+ <%= episode.synopsis %>
9
+ </div>
10
+
11
+ <div class="tags">
12
+ <strong>Tags:</strong>
13
+ <% episode.tags.each do |tag| %>
14
+ <span class="tag"><%= tag %> </span>
15
+ <% end %>
16
+ </div>
@@ -0,0 +1,6 @@
1
+ <h2>Episodes:</h2>
2
+ <% episodes.each do |episode| %>
3
+ <div class="episode">
4
+ <%= yield episode %>
5
+ </div>
6
+ <% end %>
@@ -0,0 +1,33 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <rss xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" version="2.0">
3
+ <channel>
4
+ <title><%= config['title'] %></title>
5
+ <link><%= config['urlbase'] %></link>
6
+ <language>en</language>
7
+ <copyright>℗ &amp; © <%= config['author'] %></copyright>
8
+ <itunes:subtitle><%= config['subtitle'] %></itunes:subtitle>
9
+ <itunes:author><%= config['author'] %></itunes:author>
10
+ <itunes:summary><%= config['itunes']['summary'] %></itunes:summary>
11
+
12
+ <itunes:owner>
13
+ <itunes:name><%= config['itunes']['owner']['name'] %></itunes:name>
14
+ <itunes:email><%= config['itunes']['owner']['email'] %></itunes:email>
15
+ </itunes:owner>
16
+
17
+ <itunes:image href="<%= $itunes_image_url %>"/>
18
+ <itunes:category text="<%= config['itunes']['category'] %>"/>
19
+
20
+ <%- episodes.each do |episode| %>
21
+ <item>
22
+ <title><%= episode.title %></title>
23
+ <itunes:subtitle><%= episode.subtitle %></itunes:subtitle>
24
+ <itunes:summary><%= episode.synopsis %></itunes:summary>
25
+ <enclosure url="<%= episode.file_url %>" length="<%= episode.size %>" type="audio/mpeg"/>
26
+ <pubDate><%= episode.date.rfc2822 %></pubDate>
27
+ <itunes:duration><%= episode.duration %></itunes:duration>
28
+ <itunes:keywords><%= episode.keywords %></itunes:keywords>
29
+ </item>
30
+ <% end %>
31
+
32
+ </channel>
33
+ </rss>
@@ -0,0 +1,14 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title><%= $config['title'] %></title>
5
+ <link rel="stylesheet" type="text/css" href="/assets/stylesheet.css" />
6
+ </head>
7
+ <body>
8
+ <h1><%= link_to $config['title'], "/" %></h1>
9
+ <h2><%= $config['subtitle'] %></h2>
10
+ <hr />
11
+
12
+ <%= yield %>
13
+ </body>
14
+ </html>
@@ -0,0 +1 @@
1
+ # Fill me in!
@@ -0,0 +1,27 @@
1
+ title: Title
2
+ subtitle: Subtitle
3
+ author: Author
4
+
5
+ # Include http://, domain name, and *NO trailing slash*
6
+ urlbase: http://example.com
7
+
8
+ mp3:
9
+ # NOT YET IMPLEMENTED! Do you want to have ID3v2 tags for artist/title automatically set? N.B., may be truncated.
10
+ setartist: true
11
+ settitle: true
12
+
13
+ itunes:
14
+ summary: iTunes Summary
15
+ owner:
16
+ name: Owner
17
+ email: owner@example.com
18
+ # Category MUST be one of the ones listed here http://www.apple.com/itunes/podcasts/specs.html#categories
19
+ category: Comedy
20
+
21
+ s3:
22
+ # Set the relevant s3 endpoint here. For eu-west-1 (Ireland), use this default.
23
+ hostname: s3-eu-west-1.amazonaws.com
24
+ accesskey:
25
+ id: your-aws-access-key-id
26
+ secret: your-aws-access-key-secret
27
+ bucket: bucketname
@@ -0,0 +1,7 @@
1
+ div.episode {
2
+ border-style: solid;
3
+ border-width: 1px;
4
+ border-color: black;
5
+ padding: 10px;
6
+ margin-bottom: 10px;
7
+ }
data/woody.gemspec ADDED
@@ -0,0 +1,26 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'woody/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "woody"
8
+ gem.version = Woody::VERSION
9
+ gem.authors = ["David Robertson"]
10
+ gem.email = ["david@davidr.me"]
11
+ gem.description = "Woody"
12
+ gem.summary = "Podcast Static Site Generator"
13
+ gem.homepage = "https://github.com/DavidJRobertson/woody"
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+
20
+ gem.add_runtime_dependency 'erubis'
21
+ gem.add_runtime_dependency 'mp3info'
22
+ gem.add_runtime_dependency 'aws-s3'
23
+ gem.add_runtime_dependency 'commander'
24
+
25
+ # gem.post_install_message = "This update modifies default templates. Please run `woody update_templates` in your site directory to update them. Warning: this will destroy any modifications to your templates."
26
+ end
metadata ADDED
@@ -0,0 +1,127 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: woody
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.7
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - David Robertson
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-12-08 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: erubis
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: mp3info
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: aws-s3
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: commander
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :runtime
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ description: Woody
79
+ email:
80
+ - david@davidr.me
81
+ executables:
82
+ - woody
83
+ extensions: []
84
+ extra_rdoc_files: []
85
+ files:
86
+ - .gitignore
87
+ - Gemfile
88
+ - LICENSE.txt
89
+ - README.md
90
+ - Rakefile
91
+ - bin/woody
92
+ - lib/woody.rb
93
+ - lib/woody/version.rb
94
+ - templates/episode.html
95
+ - templates/index.html
96
+ - templates/itunes.xml
97
+ - templates/layout.html
98
+ - templates/metadata.yml
99
+ - templates/podgen-config.yml
100
+ - templates/stylesheet.css
101
+ - woody.gemspec
102
+ homepage: https://github.com/DavidJRobertson/woody
103
+ licenses: []
104
+ post_install_message:
105
+ rdoc_options: []
106
+ require_paths:
107
+ - lib
108
+ required_ruby_version: !ruby/object:Gem::Requirement
109
+ none: false
110
+ requirements:
111
+ - - ! '>='
112
+ - !ruby/object:Gem::Version
113
+ version: '0'
114
+ required_rubygems_version: !ruby/object:Gem::Requirement
115
+ none: false
116
+ requirements:
117
+ - - ! '>='
118
+ - !ruby/object:Gem::Version
119
+ version: '0'
120
+ requirements: []
121
+ rubyforge_project:
122
+ rubygems_version: 1.8.24
123
+ signing_key:
124
+ specification_version: 3
125
+ summary: Podcast Static Site Generator
126
+ test_files: []
127
+ has_rdoc: