Module: Fir::Tasks

Defined in:
lib/fir/tasks.rb

Defined Under Namespace

Classes: Rsyncer

Class Method Summary collapse

Class Method Details

.defineObject



3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/fir/tasks.rb', line 3

def self.define
	namespace :users do
		desc 'Add a user for the content management API. If the user already exists, the password is overwritten. ' +
			'You must restart your server for the change to take effect. Usage: rake add_user user=username pass=password'
		task :add do
			require 'fir'
			require 'active_support/secure_random'
			unless (ENV.has_key?('user') or ENV.has_key?('USER')) and (ENV.has_key?('pass') or ENV.has_key?('PASS'))
				puts 'usage: rake users:add user=username pass=password'
				exit
			end
			user = ENV['user'] || ENV['USER']
			pass = ENV['pass'] || ENV['PASS']
			
			if File.exists?('users.yml')
				pairs = YAML::load(File.read('users.yml')) || {}
			else
				pairs = {}
			end
			
			salt = ActiveSupport::SecureRandom.hex(13)
			pairs[user] = {'crypted_password' => Fir.encrypt_password(pass, salt), 'salt' => salt}
			
			File.open('users.yml', 'w') do |file|
				file.write(YAML::dump(pairs))
			end
		end
	end
	desc 'Export the site to static HTML. (For web hosts that don\'t support Rack. Creates an .htaccess file for pretty URLs. mod_rewrite must be enabled!) ' +
		'Usage: rake export dir=path_to_export_to'
	task :export do
		require 'fileutils'
		
		if !ENV.has_key?('dir') or ENV['dir'].empty?
			puts 'Usage: rake export dir=path_to_export_to'
			exit
		end
		
		copy_to = ENV['dir']
		unless ENV['force'] or !File.exists?(copy_to) or Dir.entries(copy_to).length == 2
			puts 'Directory is not empty. Export aborted. Use "rake export dir=path force=1" to override. This will delete everything in the directory!'
			exit
		end
		
		page_config = YAML.load(File.read(File.join(FIR_ROOT, 'pages.yml')))
		path_mappings = page_config.inject({}) do |mappings, (page, configs)|
			mappings[configs['path']] = page if configs['path']
			mappings
		end
		inverted_path_mappings = path_mappings.invert
		
		pages_dir = File.join(FIR_ROOT, 'pages')
		# Get all the page files without extensions
		paths = Dir.glob(pages_dir + '/**/**').inject([]) do |result, file|
			file.gsub!(pages_dir + '/', '')
			is_erb = !!file.match(/\.erb$/)
			file.sub!(/#{File.extname(file)}$/, '')
			if is_erb
				# This was something like .html.erb, so we need to remove two extensions
				file.sub!(/#{File.extname(file)}$/, '')
			end
			# If this is a directory index, then we'll already get it when the directory is picked up in the glob.
			if !file.match(/index$/)
				unless inverted_path_mappings.has_key?(file)
					result << file
				end
			end
			result
		end + path_mappings.keys
		paths << '' # Get the home page
		
		puts "Exporting to #{copy_to}..."
		
		Fir.config.force_caching = true
		require File.expand_path(File.join(FIR_ROOT, 'config.rb'))
		builder = Rack::Builder.new(&Fir.boot_proc)
		
		puts 'Getting each page to generate the cache...'				
		paths.each do |path|
			puts '  GET ' + path
			builder.call({'PATH_INFO' => '/' + path})
		end
		
		copy_from = File.join(FIR_ROOT, 'public', '.')
		if File.exists?(copy_to)
			FileUtils.rm_rf(copy_to)
		end
		Dir.mkdir(copy_to)
		FileUtils.cp_r(copy_from, copy_to)
		FileUtils.cp_r(File.join(copy_to, 'cache', '.'), copy_to)
		FileUtils.rm_rf(File.join(copy_to, 'cache'))
		['.htaccess', 'dispatch.cgi'].each do |file|
			path = File.join(copy_to, file)
			if File.exists?(path)
				File.delete(path)
			end
		end
		# Create a simple .htaccess file to enable pretty URLs
		htaccess =
		"DirectoryIndex index.html\n" +
		"RewriteEngine On\n" +
		"RewriteCond %{REQUEST_FILENAME} !-f\n" +
		"RewriteCond %{REQUEST_FILENAME} !-d\n" +
		"RewriteRule (.*) $1.html"
		File.open(File.join(copy_to, '.htaccess'), 'w') do |f|
			f.write(htaccess)
		end
	end
	
	desc "Export the site to static HTML and transfer it to the server using rsync and SSH. (For web hosts that don't support Rack. " +
		"Creates an .htaccess file for pretty URLs. mod_rewrite must be enabled!) " +
		"Example usage: rake export_to_server [email protected]:/home/username/public_html\n\n" +
		"Obviously, dest should be set to the correct rsync destination for your deploy environment. " +
		"Note that dest is NOT a URI, even though it sort of looks like one. It's a destination string in the form that rsync accepts."
	task :export_to_server do
		begin
			ENV['dir'] = '.server_export_tmp'
			Rake::Task['export'].execute
			if ENV['dest']
				dest = ENV['dest']
			elsif File.exists?(File.join(FIR_ROOT, 'deploy.yml'))
				yaml = YAML.load(File.read(File.join(FIR_ROOT, 'deploy.yml')))
				['host', 'user', 'path'].each do |param|
					unless yaml.has_key?(param)
						puts "deploy.yml must specify #{param}"
						exit
					end
				end
				dest = "#{yaml['user']}@#{yaml['host']}:#{yaml['path']}"
			else
				puts "Example usage: rake export_to_server [email protected]/home:/username/public_html"
				exit
			end
			Rsyncer.new.run(dest)
		ensure
			FileUtils.rm_rf '.server_export_tmp'
		end
	end
end