woody 0.0.11 → 0.0.12
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 +1 -0
- data/bin/woody +6 -6
- data/lib/woody/compiler.rb +116 -0
- data/lib/woody/deployer.rb +67 -0
- data/lib/woody/episode.rb +64 -0
- data/lib/woody/generator.rb +54 -0
- data/lib/woody/version.rb +1 -1
- data/lib/woody.rb +4 -279
- metadata +5 -1
data/.gitignore
CHANGED
data/bin/woody
CHANGED
@@ -13,7 +13,7 @@ command :compile do |c|
|
|
13
13
|
c.description = "Compiles the site"
|
14
14
|
c.action do |args, options|
|
15
15
|
Woody.init
|
16
|
-
Woody.compile
|
16
|
+
Woody::Compiler.compile
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
@@ -21,7 +21,7 @@ command :deploy do |c|
|
|
21
21
|
c.description = "Deploys the site"
|
22
22
|
c.action do |args, options|
|
23
23
|
Woody.init
|
24
|
-
Woody.deploy
|
24
|
+
Woody::Deployer.deploy
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
@@ -29,8 +29,8 @@ command :cd do |c|
|
|
29
29
|
c.description = "Compiles then deploys the site"
|
30
30
|
c.action do |args, options|
|
31
31
|
Woody.init
|
32
|
-
Woody.compile
|
33
|
-
Woody.deploy
|
32
|
+
Woody::Compiler.compile
|
33
|
+
Woody::Deployer.deploy
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
@@ -42,7 +42,7 @@ command :new do |c|
|
|
42
42
|
puts "Syntax: woody new [sitename]"
|
43
43
|
exit!
|
44
44
|
end
|
45
|
-
Woody::new_site(args[0])
|
45
|
+
Woody::Generator.new_site(args[0])
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
@@ -50,6 +50,6 @@ command :update_templates do |c|
|
|
50
50
|
c.description = "Sets template files to current default. DESTRUCTIVE!"
|
51
51
|
c.action do |args, options|
|
52
52
|
Woody.init
|
53
|
-
Woody::update_templates
|
53
|
+
Woody::Generator.update_templates
|
54
54
|
end
|
55
55
|
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
module Woody
|
2
|
+
module Compiler
|
3
|
+
def self.compile()
|
4
|
+
puts "Compiling..."
|
5
|
+
meta = YAML.load_file("content/metadata.yml")
|
6
|
+
|
7
|
+
episodes = Array.new
|
8
|
+
filesfound = Array.new
|
9
|
+
touchedfiles = Array.new
|
10
|
+
Dir.glob('content/*.mp3') do |file|
|
11
|
+
filename = file[8..-1]
|
12
|
+
unless meta == false or meta[filename].nil?
|
13
|
+
# Episode metadata already stored
|
14
|
+
episodes << Episode.new_from_meta(filename, meta[filename])
|
15
|
+
filesfound << filename
|
16
|
+
else
|
17
|
+
# No episode metadata stored for this yet
|
18
|
+
|
19
|
+
puts "Warning: no metadata found for file #{filename}"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# Check for files in meta but not found
|
24
|
+
unless meta == false
|
25
|
+
meta.each do |file|
|
26
|
+
next if filesfound.include? file[0]
|
27
|
+
puts "Warning: found metadata for file #{file[0]}, but file itself is missing. Will not be published."
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# Make sure necessary directories exist
|
32
|
+
FileUtils.mkdir_p('output/assets') unless File.directory?('output/assets')
|
33
|
+
FileUtils.mkdir_p('output/assets/mp3') unless File.directory?('output/assets/mp3')
|
34
|
+
FileUtils.mkdir_p('output/episode') unless File.directory?('output/episode')
|
35
|
+
|
36
|
+
# Copy over (TODO: and process) MP3 files
|
37
|
+
episodes.each do |episode|
|
38
|
+
FileUtils.copy "content/#{episode.filename}", "output/assets/mp3/#{episode.compiledname}"
|
39
|
+
touchedfiles << "assets/mp3/#{episode.compiledname}"
|
40
|
+
end
|
41
|
+
|
42
|
+
# Copy over assets
|
43
|
+
Dir.foreach("templates/assets") do |item|
|
44
|
+
next if item == '.' or item == '..'
|
45
|
+
begin
|
46
|
+
FileUtils.copy "templates/assets/#{item}", "output/assets/#{item}"
|
47
|
+
touchedfiles << "assets/#{item}"
|
48
|
+
rescue Errno::EISDIR
|
49
|
+
puts "Warning: subdirectories in templates/assets are ignored!"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# Update index.html
|
54
|
+
layout = File.read('templates/layout.html')
|
55
|
+
layout = Erubis::Eruby.new(layout)
|
56
|
+
|
57
|
+
index_compiled = layout.result(config: $config, episodes: episodes) do
|
58
|
+
index = Erubis::Eruby.new(File.read('templates/index.html'))
|
59
|
+
index.result(config: $config, episodes: episodes, test: "hello, world") do |episode|
|
60
|
+
ep = Erubis::Eruby.new(File.read('templates/episode.html'))
|
61
|
+
ep.result(config: $config, episodes: episodes, episode: episode)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
File.open('output/index.html', 'w') {|f| f.write(index_compiled) }
|
65
|
+
touchedfiles << 'index.html'
|
66
|
+
|
67
|
+
# Update episode pages
|
68
|
+
episodes.each do |episode|
|
69
|
+
layout = File.read('templates/layout.html')
|
70
|
+
layout = Erubis::Eruby.new(layout)
|
71
|
+
episode_compiled = layout.result(config: $config, episodes: episodes) do
|
72
|
+
ep = Erubis::Eruby.new(File.read('templates/episode.html'))
|
73
|
+
ep.result(config: $config, episodes: episodes, episode: episode)
|
74
|
+
end
|
75
|
+
File.open("output/#{episode.path(false)}", 'w') {|f| f.write(episode_compiled) }
|
76
|
+
touchedfiles << episode.path(false)
|
77
|
+
end
|
78
|
+
|
79
|
+
# Copy over iTunes.png
|
80
|
+
if File.exist? "content/iTunes.png"
|
81
|
+
FileUtils.copy "content/iTunes.png", "output/assets/iTunes.png"
|
82
|
+
touchedfiles << "assets/iTunes.png"
|
83
|
+
else
|
84
|
+
puts "Warning: content/iTunes.png missing!"
|
85
|
+
end
|
86
|
+
|
87
|
+
# Update iTunes RSS
|
88
|
+
itunes = File.read "#{$source_root}/itunes.xml" # Use itunes.xml template in gem, not in site's template folder.
|
89
|
+
itunes = Erubis::Eruby.new(itunes)
|
90
|
+
itunes_compiled = itunes.result(config: $config, episodes: episodes)
|
91
|
+
File.open("output/itunes.xml", 'w') {|f| f.write(itunes_compiled) }
|
92
|
+
touchedfiles << "itunes.xml"
|
93
|
+
|
94
|
+
|
95
|
+
# Update General RSS
|
96
|
+
|
97
|
+
|
98
|
+
# Purge left over files
|
99
|
+
purge_output(touchedfiles)
|
100
|
+
end
|
101
|
+
|
102
|
+
private
|
103
|
+
|
104
|
+
def self.purge_output(touchedfiles, subdir = "")
|
105
|
+
Dir.foreach("output/#{subdir}") do |item|
|
106
|
+
next if item == '.' or item == '..'
|
107
|
+
p = "#{subdir}#{item}"
|
108
|
+
begin
|
109
|
+
File.delete "output/#{subdir}#{item}" unless touchedfiles.include? p
|
110
|
+
rescue Errno::EISDIR, Errno::EPERM # Rescuing EPERM seems to be necessary on macs, hmm :/
|
111
|
+
purge_output touchedfiles, "#{p}/"
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module Woody
|
2
|
+
module Deployer
|
3
|
+
def self.deploy
|
4
|
+
touchedfiles = Array.new
|
5
|
+
deploy_r touchedfiles
|
6
|
+
|
7
|
+
# Purge left over files
|
8
|
+
purge_bucket touchedfiles
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def self.deploy_r(touchedfiles, subdir = "")
|
14
|
+
puts "Deploying... " if subdir == ""
|
15
|
+
Dir.foreach("output/#{subdir}") do |item|
|
16
|
+
next if item == '.' or item == '..'
|
17
|
+
begin
|
18
|
+
touchedfiles << "#{subdir}#{item}"
|
19
|
+
upload("#{subdir}#{item}", "output/#{subdir}#{item}")
|
20
|
+
rescue Errno::EISDIR
|
21
|
+
deploy_r touchedfiles, "#{subdir}#{item}/"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.purge_bucket(touchedfiles)
|
27
|
+
bucket = AWS::S3::Bucket.find $bucketname
|
28
|
+
bucket.objects.each do |object|
|
29
|
+
object.delete unless touchedfiles.include? object.key
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.filehash(filepath)
|
34
|
+
sha1 = Digest::SHA1.new
|
35
|
+
File.open(filepath) do|file|
|
36
|
+
buffer = ''
|
37
|
+
# Read the file 512 bytes at a time
|
38
|
+
while not file.eof
|
39
|
+
file.read(512, buffer)
|
40
|
+
sha1.update(buffer)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
return sha1.to_s
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.upload(objectname, filepath)
|
47
|
+
# Generate hash of file
|
48
|
+
hash = filehash filepath
|
49
|
+
|
50
|
+
# Get hash of version already uploaded, if available.
|
51
|
+
begin
|
52
|
+
object = AWS::S3::S3Object.find objectname, $bucketname
|
53
|
+
oldhash = object.metadata['hash']
|
54
|
+
rescue AWS::S3::NoSuchKey
|
55
|
+
# File not uploaded yet
|
56
|
+
oldhash = nil
|
57
|
+
end
|
58
|
+
unless hash == oldhash
|
59
|
+
# Don't reupload if file hasn't changed
|
60
|
+
puts "#{objectname}: Uploading"
|
61
|
+
AWS::S3::S3Object.store(objectname, open(filepath), $bucketname, access: :public_read, 'x-amz-meta-hash' => hash)
|
62
|
+
else
|
63
|
+
puts "#{objectname}: Not uploading, hasn't changed since last time."
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module Woody
|
2
|
+
class Episode
|
3
|
+
def self.new_from_meta(filename, meta)
|
4
|
+
return Episode.new(filename, meta['title'], Date.parse(meta['date']), meta['synopsis'], meta['subtitle'], meta['tags'])
|
5
|
+
end
|
6
|
+
|
7
|
+
def initialize(filename, title, date, synopsis, subtitle = nil, tags = [], compiledname = nil)
|
8
|
+
@filename = filename
|
9
|
+
@title = title
|
10
|
+
@date = date
|
11
|
+
@synopsis = synopsis
|
12
|
+
@subtitle = subtitle
|
13
|
+
@tags = tags
|
14
|
+
@compiledname = compiledname
|
15
|
+
|
16
|
+
if @compiledname.nil? or @compiledname.empty?
|
17
|
+
@compiledname = @filename.gsub(/[^0-9A-Za-z .]/, '').gsub(' ', '_')
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
attr_accessor :filename, :title, :date, :synopsis, :tags, :subtitle, :compiledname
|
22
|
+
|
23
|
+
def url
|
24
|
+
return "#{$config['urlbase']}#{path}" unless path.nil?
|
25
|
+
return false
|
26
|
+
end
|
27
|
+
|
28
|
+
def path(leader=true)
|
29
|
+
return "#{leader ? "/" : ""}episode/#{@compiledname[0..-5]}.html" unless @compiledname.nil?
|
30
|
+
return false
|
31
|
+
end
|
32
|
+
|
33
|
+
def file_url
|
34
|
+
return "#{$config['urlbase']}#{file_path}" unless file_path.nil?
|
35
|
+
return false
|
36
|
+
end
|
37
|
+
|
38
|
+
def file_path(leader=true)
|
39
|
+
return "#{leader ? "/" : ""}assets/mp3/#{@compiledname}" unless @compiledname.nil?
|
40
|
+
return false
|
41
|
+
end
|
42
|
+
|
43
|
+
def keywords
|
44
|
+
@tags.join ', ' unless @tags.nil? or @tags.empty?
|
45
|
+
end
|
46
|
+
|
47
|
+
def size
|
48
|
+
File.size "content/#{filename}"
|
49
|
+
end
|
50
|
+
|
51
|
+
def duration
|
52
|
+
return @duration unless @duration.nil?
|
53
|
+
length = 0
|
54
|
+
Mp3Info.open("content/#{@filename}") do |mp3|
|
55
|
+
length = mp3.length
|
56
|
+
end
|
57
|
+
length = length.to_i
|
58
|
+
seconds = length % 60
|
59
|
+
minutes = (length / 60).to_i
|
60
|
+
@duration = "#{minutes}:#{seconds}"
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module Woody
|
2
|
+
module Generator
|
3
|
+
def self.new_site(name)
|
4
|
+
puts "Creating new site '#{name}'..."
|
5
|
+
if File.directory?(name)
|
6
|
+
puts "Error: directory '#{name}' already exists!"
|
7
|
+
return false
|
8
|
+
end
|
9
|
+
|
10
|
+
cdir_p(name)
|
11
|
+
cpy_t("woody-config.yml", "#{name}/woody-config.yml")
|
12
|
+
|
13
|
+
cdir_p("#{name}/templates")
|
14
|
+
cpy_t("layout.html", "#{name}/templates/layout.html")
|
15
|
+
cpy_t("index.html", "#{name}/templates/index.html")
|
16
|
+
cpy_t("episode.html", "#{name}/templates/episode.html")
|
17
|
+
|
18
|
+
cdir_p("#{name}/templates/assets")
|
19
|
+
cpy_t("stylesheet.css", "#{name}/templates/assets/stylesheet.css")
|
20
|
+
|
21
|
+
cdir_p("#{name}/content")
|
22
|
+
cpy_t("metadata.yml", "#{name}/content/metadata.yml")
|
23
|
+
cpy_t("iTunes.png", "#{name}/content/iTunes.png")
|
24
|
+
|
25
|
+
cdir_p("#{name}/output")
|
26
|
+
cdir_p("#{name}/output/assets")
|
27
|
+
cdir_p("#{name}/output/assets/mp3")
|
28
|
+
cdir_p("#{name}/output/episode")
|
29
|
+
|
30
|
+
puts "Done!"
|
31
|
+
puts "Now, do `cd #{name}` then edit the config file, woody-config.yml."
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.update_templates
|
35
|
+
puts "Updating templates..."
|
36
|
+
cpy_t("layout.html", "templates/layout.html")
|
37
|
+
cpy_t("index.html", "templates/index.html")
|
38
|
+
cpy_t("episode.html", "templates/episode.html")
|
39
|
+
cpy_t("stylesheet.css", "templates/assets/stylesheet.css")
|
40
|
+
puts "Done! Thanks for updating :)"
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def self.cdir_p(dir)
|
46
|
+
puts "Creating directory '#{dir}'"
|
47
|
+
FileUtils.mkdir_p(dir)
|
48
|
+
end
|
49
|
+
def self.cpy_t(source, destination)
|
50
|
+
puts "Creating file '#{destination}'"
|
51
|
+
FileUtils.cp File.join($source_root, source), destination
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
data/lib/woody/version.rb
CHANGED
data/lib/woody.rb
CHANGED
@@ -1,4 +1,8 @@
|
|
1
1
|
require "woody/version"
|
2
|
+
require "woody/episode"
|
3
|
+
require "woody/compiler"
|
4
|
+
require "woody/deployer"
|
5
|
+
require "woody/generator"
|
2
6
|
|
3
7
|
require 'yaml'
|
4
8
|
require 'erubis'
|
@@ -14,7 +18,6 @@ $VERBOSE = oldverbosity
|
|
14
18
|
|
15
19
|
module Woody
|
16
20
|
$source_root = File.expand_path("../../templates", __FILE__)
|
17
|
-
|
18
21
|
# Load configuration
|
19
22
|
def self.init
|
20
23
|
begin
|
@@ -43,284 +46,6 @@ module Woody
|
|
43
46
|
AWS::S3::DEFAULT_HOST.replace $config['s3']['hostname']
|
44
47
|
$bucketname = $config['s3']['bucket']
|
45
48
|
end
|
46
|
-
|
47
|
-
def self.new_site(name)
|
48
|
-
puts "Creating new site '#{name}'..."
|
49
|
-
if File.directory?(name)
|
50
|
-
puts "Error: directory '#{name}' already exists!"
|
51
|
-
return false
|
52
|
-
end
|
53
|
-
|
54
|
-
cdir_p(name)
|
55
|
-
cpy_t("woody-config.yml", "#{name}/woody-config.yml")
|
56
|
-
|
57
|
-
cdir_p("#{name}/templates")
|
58
|
-
cpy_t("layout.html", "#{name}/templates/layout.html")
|
59
|
-
cpy_t("index.html", "#{name}/templates/index.html")
|
60
|
-
cpy_t("episode.html", "#{name}/templates/episode.html")
|
61
|
-
|
62
|
-
cdir_p("#{name}/templates/assets")
|
63
|
-
cpy_t("stylesheet.css", "#{name}/templates/assets/stylesheet.css")
|
64
|
-
|
65
|
-
cdir_p("#{name}/content")
|
66
|
-
cpy_t("metadata.yml", "#{name}/content/metadata.yml")
|
67
|
-
cpy_t("iTunes.png", "#{name}/content/iTunes.png")
|
68
|
-
|
69
|
-
cdir_p("#{name}/output")
|
70
|
-
cdir_p("#{name}/output/assets")
|
71
|
-
cdir_p("#{name}/output/assets/mp3")
|
72
|
-
cdir_p("#{name}/output/episode")
|
73
|
-
|
74
|
-
puts "Done!"
|
75
|
-
puts "Now, do `cd #{name}` then edit the config file, woody-config.yml."
|
76
|
-
end
|
77
|
-
|
78
|
-
def self.update_templates
|
79
|
-
puts "Updating templates..."
|
80
|
-
cpy_t("layout.html", "templates/layout.html")
|
81
|
-
cpy_t("index.html", "templates/index.html")
|
82
|
-
cpy_t("episode.html", "templates/episode.html")
|
83
|
-
cpy_t("stylesheet.css", "templates/assets/stylesheet.css")
|
84
|
-
puts "Done! Thanks for updating :)"
|
85
|
-
end
|
86
|
-
|
87
|
-
def self.cdir_p(dir)
|
88
|
-
puts "Creating directory '#{dir}'"
|
89
|
-
FileUtils.mkdir_p(dir)
|
90
|
-
end
|
91
|
-
def self.cpy_t(source, destination)
|
92
|
-
puts "Creating file '#{destination}'"
|
93
|
-
FileUtils.cp File.join($source_root, source), destination
|
94
|
-
end
|
95
|
-
|
96
|
-
class Episode
|
97
|
-
def self.new_from_meta(filename, meta)
|
98
|
-
return Episode.new(filename, meta['title'], Date.parse(meta['date']), meta['synopsis'], meta['subtitle'], meta['tags'])
|
99
|
-
end
|
100
|
-
def initialize(filename, title, date, synopsis, subtitle = nil, tags = [], compiledname = nil)
|
101
|
-
@filename = filename
|
102
|
-
@title = title
|
103
|
-
@date = date
|
104
|
-
@synopsis = synopsis
|
105
|
-
@subtitle = subtitle
|
106
|
-
@tags = tags
|
107
|
-
@compiledname = compiledname
|
108
|
-
|
109
|
-
if @compiledname.nil? or @compiledname.empty?
|
110
|
-
@compiledname = @filename.gsub(/[^0-9A-Za-z .]/, '').gsub(' ','_')
|
111
|
-
end
|
112
|
-
end
|
113
|
-
attr_accessor :filename, :title, :date, :synopsis, :tags, :subtitle, :compiledname
|
114
|
-
def duration
|
115
|
-
return @duration unless @duration.nil?
|
116
|
-
length = 0
|
117
|
-
Mp3Info.open("content/#{@filename}") do |mp3|
|
118
|
-
length = mp3.length
|
119
|
-
end
|
120
|
-
length = length.to_i
|
121
|
-
seconds = length % 60
|
122
|
-
minutes = (length / 60).to_i
|
123
|
-
@duration = "#{minutes}:#{seconds}"
|
124
|
-
end
|
125
|
-
def size
|
126
|
-
File.size "content/#{filename}"
|
127
|
-
end
|
128
|
-
def keywords
|
129
|
-
@tags.join ', ' unless @tags.nil? or @tags.empty?
|
130
|
-
end
|
131
|
-
def file_path(leader=true)
|
132
|
-
return "#{leader ? "/" : ""}assets/mp3/#{@compiledname}" unless @compiledname.nil?
|
133
|
-
return false
|
134
|
-
end
|
135
|
-
def file_url
|
136
|
-
return "#{$config['urlbase']}#{file_path}" unless file_path.nil?
|
137
|
-
return false
|
138
|
-
end
|
139
|
-
def path(leader=true)
|
140
|
-
return "#{leader ? "/" : ""}episode/#{@compiledname[0..-5]}.html" unless @compiledname.nil?
|
141
|
-
return false
|
142
|
-
end
|
143
|
-
def url
|
144
|
-
return "#{$config['urlbase']}#{path}" unless path.nil?
|
145
|
-
return false
|
146
|
-
end
|
147
|
-
end
|
148
|
-
|
149
|
-
def self.compile()
|
150
|
-
puts "Compiling..."
|
151
|
-
meta = YAML.load_file("content/metadata.yml")
|
152
|
-
|
153
|
-
episodes = Array.new
|
154
|
-
filesfound = Array.new
|
155
|
-
touchedfiles = Array.new
|
156
|
-
Dir.glob('content/*.mp3') do |file|
|
157
|
-
filename = file[8..-1]
|
158
|
-
unless meta == false or meta[filename].nil?
|
159
|
-
# Episode metadata already stored
|
160
|
-
episodes << Episode.new_from_meta(filename, meta[filename])
|
161
|
-
filesfound << filename
|
162
|
-
else
|
163
|
-
# No episode metadata stored for this yet
|
164
|
-
|
165
|
-
puts "Warning: no metadata found for file #{filename}"
|
166
|
-
end
|
167
|
-
end
|
168
|
-
|
169
|
-
# Check for files in meta but not found
|
170
|
-
unless meta == false
|
171
|
-
meta.each do |file|
|
172
|
-
next if filesfound.include? file[0]
|
173
|
-
puts "Warning: found metadata for file #{file[0]}, but file itself is missing. Will not be published."
|
174
|
-
end
|
175
|
-
end
|
176
|
-
|
177
|
-
# Make sure necessary directories exist
|
178
|
-
FileUtils.mkdir_p('output/assets') unless File.directory?('output/assets')
|
179
|
-
FileUtils.mkdir_p('output/assets/mp3') unless File.directory?('output/assets/mp3')
|
180
|
-
FileUtils.mkdir_p('output/episode') unless File.directory?('output/episode')
|
181
|
-
|
182
|
-
# Copy over (TODO: and process) MP3 files
|
183
|
-
episodes.each do |episode|
|
184
|
-
FileUtils.copy "content/#{episode.filename}", "output/assets/mp3/#{episode.compiledname}"
|
185
|
-
touchedfiles << "assets/mp3/#{episode.compiledname}"
|
186
|
-
end
|
187
|
-
|
188
|
-
# Copy over assets
|
189
|
-
Dir.foreach("templates/assets") do |item|
|
190
|
-
next if item == '.' or item == '..'
|
191
|
-
begin
|
192
|
-
FileUtils.copy "templates/assets/#{item}", "output/assets/#{item}"
|
193
|
-
touchedfiles << "assets/#{item}"
|
194
|
-
rescue Errno::EISDIR
|
195
|
-
puts "Warning: subdirectories in templates/assets are ignored!"
|
196
|
-
end
|
197
|
-
end
|
198
|
-
|
199
|
-
# Update index.html
|
200
|
-
layout = File.read('templates/layout.html')
|
201
|
-
layout = Erubis::Eruby.new(layout)
|
202
|
-
|
203
|
-
index_compiled = layout.result(config: $config, episodes: episodes) do
|
204
|
-
index = Erubis::Eruby.new(File.read('templates/index.html'))
|
205
|
-
index.result(config: $config, episodes: episodes, test: "hello, world") do |episode|
|
206
|
-
ep = Erubis::Eruby.new(File.read('templates/episode.html'))
|
207
|
-
ep.result(config: $config, episodes: episodes, episode: episode)
|
208
|
-
end
|
209
|
-
end
|
210
|
-
File.open('output/index.html', 'w') {|f| f.write(index_compiled) }
|
211
|
-
touchedfiles << 'index.html'
|
212
|
-
|
213
|
-
# Update episode pages
|
214
|
-
episodes.each do |episode|
|
215
|
-
layout = File.read('templates/layout.html')
|
216
|
-
layout = Erubis::Eruby.new(layout)
|
217
|
-
episode_compiled = layout.result(config: $config, episodes: episodes) do
|
218
|
-
ep = Erubis::Eruby.new(File.read('templates/episode.html'))
|
219
|
-
ep.result(config: $config, episodes: episodes, episode: episode)
|
220
|
-
end
|
221
|
-
File.open("output/#{episode.path(false)}", 'w') {|f| f.write(episode_compiled) }
|
222
|
-
touchedfiles << episode.path(false)
|
223
|
-
end
|
224
|
-
|
225
|
-
# Copy over iTunes.png
|
226
|
-
if File.exist? "content/iTunes.png"
|
227
|
-
FileUtils.copy "content/iTunes.png", "output/assets/iTunes.png"
|
228
|
-
touchedfiles << "assets/iTunes.png"
|
229
|
-
else
|
230
|
-
puts "Warning: content/iTunes.png missing!"
|
231
|
-
end
|
232
|
-
|
233
|
-
# Update iTunes RSS
|
234
|
-
itunes = File.read "#{$source_root}/itunes.xml" # Use itunes.xml template in gem, not in site's template folder.
|
235
|
-
itunes = Erubis::Eruby.new(itunes)
|
236
|
-
itunes_compiled = itunes.result(config: $config, episodes: episodes)
|
237
|
-
File.open("output/itunes.xml", 'w') {|f| f.write(itunes_compiled) }
|
238
|
-
touchedfiles << "itunes.xml"
|
239
|
-
|
240
|
-
|
241
|
-
# Update General RSS
|
242
|
-
|
243
|
-
|
244
|
-
# Purge left over files
|
245
|
-
purge_output(touchedfiles)
|
246
|
-
end
|
247
|
-
|
248
|
-
def self.purge_output(touchedfiles, subdir = "")
|
249
|
-
Dir.foreach("output/#{subdir}") do |item|
|
250
|
-
next if item == '.' or item == '..'
|
251
|
-
p = "#{subdir}#{item}"
|
252
|
-
begin
|
253
|
-
File.delete "output/#{subdir}#{item}" unless touchedfiles.include? p
|
254
|
-
rescue Errno::EISDIR, Errno::EPERM # Rescuing EPERM seems to be necessary on macs, hmm :/
|
255
|
-
purge_output touchedfiles, "#{p}/"
|
256
|
-
end
|
257
|
-
end
|
258
|
-
end
|
259
|
-
|
260
|
-
def self.deploy
|
261
|
-
touchedfiles = Array.new
|
262
|
-
deploy_r touchedfiles
|
263
|
-
|
264
|
-
# Purge left over files
|
265
|
-
purge_bucket touchedfiles
|
266
|
-
end
|
267
|
-
|
268
|
-
def self.deploy_r(touchedfiles, subdir = "")
|
269
|
-
puts "Deploying... " if subdir == ""
|
270
|
-
Dir.foreach("output/#{subdir}") do |item|
|
271
|
-
next if item == '.' or item == '..'
|
272
|
-
begin
|
273
|
-
touchedfiles << "#{subdir}#{item}"
|
274
|
-
upload("#{subdir}#{item}", "output/#{subdir}#{item}")
|
275
|
-
rescue Errno::EISDIR
|
276
|
-
deploy_r touchedfiles, "#{subdir}#{item}/"
|
277
|
-
end
|
278
|
-
end
|
279
|
-
end
|
280
|
-
|
281
|
-
def self.purge_bucket(touchedfiles)
|
282
|
-
bucket = AWS::S3::Bucket.find $bucketname
|
283
|
-
bucket.objects.each do |object|
|
284
|
-
object.delete unless touchedfiles.include? object.key
|
285
|
-
end
|
286
|
-
end
|
287
|
-
|
288
|
-
def self.filehash(filepath)
|
289
|
-
sha1 = Digest::SHA1.new
|
290
|
-
File.open(filepath) do|file|
|
291
|
-
buffer = ''
|
292
|
-
# Read the file 512 bytes at a time
|
293
|
-
while not file.eof
|
294
|
-
file.read(512, buffer)
|
295
|
-
sha1.update(buffer)
|
296
|
-
end
|
297
|
-
end
|
298
|
-
return sha1.to_s
|
299
|
-
end
|
300
|
-
|
301
|
-
def self.upload(objectname, filepath)
|
302
|
-
# Generate hash of file
|
303
|
-
hash = filehash filepath
|
304
|
-
|
305
|
-
# Get hash of version already uploaded, if available.
|
306
|
-
begin
|
307
|
-
object = AWS::S3::S3Object.find objectname, $bucketname
|
308
|
-
oldhash = object.metadata['hash']
|
309
|
-
rescue AWS::S3::NoSuchKey
|
310
|
-
# File not uploaded yet
|
311
|
-
oldhash = nil
|
312
|
-
end
|
313
|
-
unless hash == oldhash
|
314
|
-
# Don't reupload if file hasn't changed
|
315
|
-
puts "#{objectname}: Uploading"
|
316
|
-
AWS::S3::S3Object.store(objectname, open(filepath), $bucketname, access: :public_read, 'x-amz-meta-hash' => hash)
|
317
|
-
else
|
318
|
-
puts "#{objectname}: Not uploading, hasn't changed since last time."
|
319
|
-
end
|
320
|
-
end
|
321
|
-
|
322
|
-
|
323
|
-
|
324
49
|
|
325
50
|
end
|
326
51
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: woody
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.12
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -90,6 +90,10 @@ files:
|
|
90
90
|
- Rakefile
|
91
91
|
- bin/woody
|
92
92
|
- lib/woody.rb
|
93
|
+
- lib/woody/compiler.rb
|
94
|
+
- lib/woody/deployer.rb
|
95
|
+
- lib/woody/episode.rb
|
96
|
+
- lib/woody/generator.rb
|
93
97
|
- lib/woody/version.rb
|
94
98
|
- templates/episode.html
|
95
99
|
- templates/iTunes.png
|