File: lib/radiant/setup.rb

Overview
Module Structure
Class Hierarchy
Code

Overview

Module Structure

  module: <Toplevel Module>
  module: Radiant#4
  class: Setup#5
extends
  Forwardable   
inherits from
  Object ( Builtin-Module )
has properties
class method: bootstrap (1/2) / 1 #8
attribute: config [RW] #15
method: bootstrap (2/E) / 1 #17
method: create_admin_user / 3 #26
method: load_default_configuration #46
method: load_database_template / 1 #59
method: prompt_for_admin_name #91
method: prompt_for_admin_username #101
method: prompt_for_admin_password #111
method: find_template_in_path / 1 #122
method: find_and_load_templates / 1 #141
method: load_template_file / 1 #147
method: create_records / 1 #151
method: model / 1 #170
method: order_by_id / 1 #174
method: terminal #181
method: output #185
method: wrap / 1 #189
method: print / 1 #194
method: puts / 1 #199
method: announce / 1 #203
method: feedback / 2 #207
method: step #221

Class Hierarchy

Object ( Builtin-Module )
  Setup ( Radiant ) #5

Code

   1  require "highline"
   2  require "forwardable"
   3 
   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."
  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          step { Radiant::Config['defaults.page.filter' ] = nil }
  53          step { Radiant::Config['defaults.page.fields'] = 'Keywords, Description' }
  54          step { Radiant::Config['session_timeout'] = 2.weeks }
  55          step { Radiant::Config['default_locale'] = 'en' }
  56        end
  57      end
  58      
  59      def load_database_template(filename)
  60        template = nil
  61        if filename
  62          name = find_template_in_path(filename)
  63          unless name
  64            announce "Invalid template name: #{filename}"
  65            filename = nil
  66          else
  67            template = load_template_file(name)
  68          end
  69        end
  70        unless filename
  71          templates = find_and_load_templates("#{RADIANT_ROOT}/db/templates/*.yml")
  72          templates.concat find_and_load_templates("#{RADIANT_ROOT}/vendor/extensions/**/db/templates/*.yml")
  73          Radiant::Extension.descendants.each do |d|
  74            templates.concat find_and_load_templates(d.root + '/db/templates/*.yml')
  75          end
  76          templates.concat find_and_load_templates("#{Rails.root}/vendor/extensions/**/db/templates/*.yml")
  77          templates.concat find_and_load_templates("#{Rails.root}/db/templates/*.yml")
  78          templates.uniq!
  79          choose do |menu|
  80            menu.header = "\nSelect a database template"
  81            menu.prompt = "[1-#{templates.size}]: "
  82            menu.select_by = :index
  83            templates.each { |t| menu.choice(t['name']) { template = t } }
  84          end
  85        end
  86        create_records(template)
  87      end
  88          
  89      private
  90        
  91        def prompt_for_admin_name
  92          username = ask('Name (Administrator): ', String) do |q|
  93            q.validate = /^.{0,100}$/
  94            q.responses[:not_valid] = "Invalid name. Must be at less than 100 characters long."
  95            q.whitespace = :strip
  96          end
  97          username = "Administrator" if username.blank?
  98          username
  99        end
 100        
 101        def prompt_for_admin_username
 102          username = ask('Username (admin): ', String) do |q|
 103            q.validate = /^(|.{3,40})$/
 104            q.responses[:not_valid] = "Invalid username. Must be at least 3 characters long."
 105            q.whitespace = :strip
 106          end
 107          username = "admin" if username.blank?
 108          username
 109        end
 110        
 111        def prompt_for_admin_password
 112          password = ask('Password (radiant): ', String) do |q|
 113            q.echo = false unless defined?(::JRuby) # JRuby doesn't support stty interaction
 114            q.validate = /^(|.{5,40})$/
 115            q.responses[:not_valid] = "Invalid password. Must be at least 5 characters long."
 116            q.whitespace = :strip
 117          end
 118          password = "radiant" if password.blank?
 119          password
 120        end
 121        
 122        def find_template_in_path(filename)
 123          (
 124            [
 125              filename,
 126              "#{RADIANT_ROOT}/#{filename}",
 127              "#{RADIANT_ROOT}/db/templates/#{filename}",
 128              "#{Rails.root}/#{filename}",
 129              "#{Rails.root}/db/templates/#{filename}",
 130              "#{Dir.pwd}/#{filename}",
 131              "#{Dir.pwd}/db/templates/#{filename}"
 132            ] +
 133            Dir.glob("#{RADIANT_ROOT}/vendor/extensions/**/db/templates/#{filename}") + 
 134            Dir.glob("#{Rails.root}/vendor/extensions/**/db/templates/#{filename}") +
 135            Radiant::Extension.descendants.inject([]) do |r, d|
 136              r << "#{d.root}/db/templates/#{filename}"
 137            end
 138          ).find { |name| File.file?(name) }
 139        end
 140        
 141        def find_and_load_templates(glob)
 142          templates = Dir[glob]
 143          templates.map! { |template| load_template_file(template) }
 144          templates.sort_by { |template| template['name'] }
 145        end
 146        
 147        def load_template_file(filename)
 148          YAML.load_file(filename)
 149        end
 150        
 151        def create_records(template)
 152          records = template['records']
 153          if records
 154            puts
 155            records.keys.each do |key|
 156              feedback "Creating #{key.to_s.underscore.humanize}" do
 157                model = model(key)
 158                model.reset_column_information
 159                record_pairs = order_by_id(records[key])
 160                step do
 161                  record_pairs.each do |id, record|
 162                    model.new(record).save
 163                  end
 164                end
 165              end
 166            end
 167          end
 168        end
 169        
 170        def model(model_name)
 171          model_name.to_s.singularize.constantize
 172        end
 173        
 174        def order_by_id(records)
 175          records.map { |name, record| [record['id'], record] }.sort { |a, b| a[0] <=> b[0] }
 176        end
 177        
 178        extend Forwardable
 179        def_delegators :terminal, :agree, :ask, :choose, :say
 180    
 181        def terminal
 182          @terminal ||= HighLine.new
 183        end
 184    
 185        def output
 186          terminal.instance_variable_get("@output")
 187        end
 188    
 189        def wrap(string)
 190          string = terminal.send(:wrap, string) unless terminal.wrap_at.nil?
 191          string
 192        end
 193    
 194        def print(string)
 195          output.print(wrap(string))
 196          output.flush
 197        end
 198    
 199        def puts(string = "\n")
 200          say string
 201        end
 202    
 203        def announce(string)
 204          puts "\n#{string}"
 205        end
 206              
 207        def feedback(process, &block)
 208          print "#{process}..."
 209          if yield
 210            puts "OK"
 211            true
 212          else
 213            puts "FAILED"
 214            false
 215          end
 216        rescue Exception => e
 217          puts "FAILED"
 218          raise e
 219        end
 220        
 221        def step
 222          yield if block_given?
 223          print '.'
 224        end
 225        
 226    end
 227  en