woody 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +21 -0
- data/Rakefile +1 -0
- data/bin/woody +58 -0
- data/lib/woody/version.rb +3 -0
- data/lib/woody.rb +306 -0
- data/templates/episode.html +16 -0
- data/templates/index.html +6 -0
- data/templates/itunes.xml +33 -0
- data/templates/layout.html +14 -0
- data/templates/metadata.yml +1 -0
- data/templates/podgen-config.yml +27 -0
- data/templates/stylesheet.css +7 -0
- data/woody.gemspec +26 -0
- metadata +127 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
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
|
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,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>℗ & © <%= 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
|
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:
|