woody 0.0.7
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/.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:
|