Renamed helpers to correspond to renamed Controller classes.
[merb_radiant.git] / lib / radiant / .svn / text-base / setup.rb.svn-base
blob4c678fd2036c0fb1b4eb086317e3a84b4c121ac0
1 require "highline"
2 require "forwardable"
4 module Radiant
5   class Setup
6   
7     class << self
8       def bootstrap(config)
9         setup = new
10         setup.bootstrap(config)
11         setup
12       end
13     end
14     
15     attr_accessor :config
16     
17     def bootstrap(config)
18       @config = config
19       @admin = create_admin_user(config[:admin_name], config[:admin_username], config[:admin_password])
20       UserActionObserver.current_user = @admin
21       load_default_configuration
22       load_database_template(config[:database_template])
23       announce "Finished.\n\n"
24     end
25     
26     def create_admin_user(name, username, password)
27       unless name and username and password
28         announce "Create the admin user (press enter for defaults)."
29         name = prompt_for_admin_name unless name
30         username = prompt_for_admin_username unless username
31         password = prompt_for_admin_password unless password
32       end
33       attributes = {
34         :name => name,
35         :login => username,
36         :password => password,
37         :password_confirmation => password,
38         :admin => true
39       }
40       admin = User.find_by_login(username)
41       admin = User.new unless admin
42       admin.update_attributes(attributes)
43       admin
44     end
45     
46     def load_default_configuration
47       feedback "\nInitializing configuration" do
48         step { Radiant::Config['admin.title'   ] = 'Radiant CMS' }
49         step { Radiant::Config['admin.subtitle'] = 'Publishing for Small Teams' }
50         step { Radiant::Config['defaults.page.parts' ] = 'body, extended' }
51         step { Radiant::Config['defaults.page.status' ] = 'draft' }
52       end
53     end
54     
55     def load_database_template(filename)
56       template = nil
57       if filename
58         name = find_template_in_path(filename)
59         unless name
60           announce "Invalid template name: #{filename}"
61           filename = nil
62         else
63           template = load_template_file(name)
64         end
65       end
66       unless filename
67         templates = find_and_load_templates("#{RADIANT_ROOT}/db/templates/*.yml")
68         choose do |menu|
69           menu.header = "\nSelect a database template"
70           menu.prompt = "[1-#{templates.size}]: "
71           menu.select_by = :index
72           templates.each { |t| menu.choice(t['name']) { template = t } }
73         end
74       end
75       create_records(template)
76     end
77         
78     private
79       
80       def prompt_for_admin_name
81         username = ask('Name (Administrator): ', String) do |q|
82           q.validate = /^.{0,100}$/
83           q.responses[:not_valid] = "Invalid name. Must be at less than 100 characters long."
84           q.whitespace = :strip
85         end
86         username = "Administrator" if username.blank?
87         username
88       end
89       
90       def prompt_for_admin_username
91         username = ask('Username (admin): ', String) do |q|
92           q.validate = /^(|.{3,40})$/
93           q.responses[:not_valid] = "Invalid username. Must be at least 3 characters long."
94           q.whitespace = :strip
95         end
96         username = "admin" if username.blank?
97         username
98       end
99       
100       def prompt_for_admin_password
101         password = ask('Password (radiant): ', String) do |q|
102           q.echo = false
103           q.validate = /^(|.{5,40})$/
104           q.responses[:not_valid] = "Invalid password. Must be at least 5 characters long."
105           q.whitespace = :strip
106         end
107         password = "radiant" if password.blank?
108         password
109       end
110       
111       def find_template_in_path(filename)
112         [
113           filename,
114           "#{RADIANT_ROOT}/#{filename}",
115           "#{RADIANT_ROOT}/db/templates/#{filename}",
116           "#{RAILS_ROOT}/#{filename}",
117           "#{RAILS_ROOT}/db/templates/#{filename}",
118           "#{Dir.pwd}/#{filename}",
119           "#{Dir.pwd}/db/templates/#{filename}",
120         ].find { |name| File.file?(name) }
121       end
122       
123       def find_and_load_templates(glob)
124         templates = Dir[glob]
125         templates.map! { |template| load_template_file(template) }
126         templates.sort_by { |template| template['name'] }
127       end
128       
129       def load_template_file(filename)
130         YAML.load_file(filename)
131       end
132       
133       def create_records(template)
134         records = template['records']
135         if records
136           puts
137           records.keys.each do |key|
138             feedback "Creating #{key.to_s.underscore.humanize}" do
139               model = model(key)
140               model.reset_column_information
141               record_pairs = order_by_id(records[key])
142               step do
143                 record_pairs.each do |id, record|
144                   model.new(record).save
145                 end
146               end
147             end
148           end
149         end
150       end
151       
152       def model(model_name)
153         model_name.to_s.singularize.constantize
154       end
155       
156       def order_by_id(records)
157         records.map { |name, record| [record['id'], record] }.sort { |a, b| a[0] <=> b[0] }
158       end
159       
160       extend Forwardable
161       def_delegators :terminal, :agree, :ask, :choose, :say
162   
163       def terminal
164         @terminal ||= HighLine.new
165       end
166   
167       def output
168         terminal.instance_variable_get("@output")
169       end
170   
171       def wrap(string)
172         string = terminal.send(:wrap, string) unless terminal.wrap_at.nil?
173         string
174       end
175   
176       def print(string)
177         output.print(wrap(string))
178         output.flush
179       end
180   
181       def puts(string = "\n")
182         say string
183       end
184   
185       def announce(string)
186         puts "\n#{string}"
187       end
188             
189       def feedback(process, &block)
190         print "#{process}..."
191         if yield
192           puts "OK"
193           true
194         else
195           puts "FAILED"
196           false
197         end
198       rescue Exception => e
199         puts "FAILED"
200         raise e
201       end
202       
203       def step
204         yield if block_given?
205         print '.'
206       end
207       
208   end