| 68 | | # Default database |
| 69 | | unless conf.database |
| 70 | | unless conf.db |
| 71 | | puts "!! No home directory found. Please specify a database file, see --help."; exit |
| 72 | | end |
| 73 | | conf.database = {:adapter => 'sqlite3', :database => conf.db} |
| 74 | | end |
| 75 | | |
| 76 | | # Load apps |
| 77 | | PATHS = ARGV.dup |
| 78 | | apps = PATHS.inject([]) do |apps, script| |
| 79 | | if File.directory? script |
| 80 | | apps.push(*Dir[File.join(script, '*.rb')]) |
| 81 | | else |
| 82 | | apps << script |
| 83 | | end |
| 84 | | end |
| 85 | | |
| 86 | | Camping::Reloader.database = conf.database |
| 87 | | Camping::Reloader.log = conf.log |
| 88 | | apps.map! { |script| Camping::Reloader.new(script) } |
| 89 | | abort("** No apps successfully loaded") unless apps.detect { |app| app.klass } |
| 90 | | |
| 91 | | def apps.find_new_scripts |
| 92 | | each { |app| app.reload_app } |
| 93 | | PATHS.each do |path| |
| 94 | | Dir[File.join(path, '*.rb')].each do |script| |
| 95 | | smount = File.basename(script, '.rb') |
| 96 | | next if detect { |x| x.mount == smount } |
| 97 | | |
| 98 | | puts "** Discovered new #{script}" |
| 99 | | app = Camping::Reloader.new(script) |
| 100 | | next unless app |
| 101 | | |
| 102 | | yield app |
| 103 | | self << app |
| 104 | | end |
| 105 | | end |
| 106 | | self.sort! { |x, y| x.mount <=> y.mount } |
| 107 | | end |
| 108 | | |
| 109 | | def apps.index_page |
| 110 | | welcome = "You are Camping" |
| 111 | | apps = self |
| 112 | | b = Markaby::Builder.new({}, {}) |
| 113 | | b = b.instance_eval do |
| 114 | | html do |
| 115 | | head do |
| 116 | | title welcome |
| 117 | | style <<-END, :type => 'text/css' |
| 118 | | body { |
| 119 | | font-family: verdana, arial, sans-serif; |
| 120 | | padding: 10px 40px; |
| 121 | | margin: 0; |
| 122 | | } |
| 123 | | h1, h2, h3, h4, h5, h6 { |
| 124 | | font-family: utopia, georgia, serif; |
| 125 | | } |
| 126 | | END |
| 127 | | end |
| 128 | | body do |
| 129 | | h1 welcome |
| 130 | | p %{Good day. These are the Camping apps you've mounted.} |
| 131 | | ul do |
| 132 | | apps.each do |app| |
| 133 | | next unless app.klass |
| 134 | | li do |
| 135 | | h3(:style => "display: inline") { a app.klass.name, :href => "/#{app.mount}" } |
| 136 | | small { text " / " ; a "View Source", :href => "/code/#{app.mount}" } |
| 137 | | end |
| 138 | | end |
| 139 | | end |
| 140 | | end |
| 141 | | end |
| 142 | | end |
| 143 | | b.to_s |
| 144 | | end |
| | 69 | # get a copy of the paths to pass to the server |
| | 70 | paths = ARGV.dup |
| 163 | | class IndexHandler < Mongrel::HttpHandler |
| 164 | | def initialize(apps, server) |
| 165 | | @apps = apps |
| 166 | | @server = server |
| 167 | | end |
| 168 | | def process(req, res) |
| 169 | | res.start(200) do |head, out| |
| 170 | | @apps.find_new_scripts do |app| |
| 171 | | @server.register "/#{app.mount}", Mongrel::Camping::CampingHandler.new(app) |
| 172 | | @server.register "/code/#{app.mount}", ViewSource.new(app) |
| 173 | | end |
| 174 | | out << @apps.index_page |
| 175 | | end |
| 176 | | end |
| 177 | | end |
| 178 | | class ViewSource < Mongrel::HttpHandler |
| 179 | | def initialize(app) |
| 180 | | @app = app |
| 181 | | end |
| 182 | | def process(req, res) |
| 183 | | res.start(200) do |head, out| |
| 184 | | head['Content-Type'] = 'text/plain' |
| 185 | | out << @app.view_source |
| 186 | | end |
| 187 | | end |
| 188 | | end |
| 189 | | begin |
| 190 | | config = Mongrel::Configurator.new :host => conf.host do |
| 191 | | listener :port => conf.port do |
| 192 | | if apps.length > 1 |
| 193 | | apps.each do |app| |
| 194 | | uri "/#{app.mount}", :handler => Mongrel::Camping::CampingHandler.new(app) |
| 195 | | uri "/code/#{app.mount}", :handler => ViewSource.new(app) |
| 196 | | end |
| 197 | | uri "/", :handler => IndexHandler.new(apps, @listener) |
| 198 | | else |
| 199 | | uri "/", :handler => Mongrel::Camping::CampingHandler.new(apps.first) |
| 200 | | end |
| 201 | | uri "/favicon.ico", :handler => Mongrel::Error404Handler.new("") |
| 202 | | trap("INT") { stop } |
| 203 | | run |
| 204 | | end |
| 205 | | end |
| 206 | | |
| 207 | | puts "** Camping running on #{conf.host}:#{conf.port}." |
| 208 | | config.join |
| 209 | | rescue Errno::EADDRINUSE |
| 210 | | puts "** ERROR : address #{conf.host}:#{conf.port} already in use." |
| 211 | | end |
| 212 | | when 'webrick' |
| 213 | | require 'webrick/httpserver' |
| 214 | | require 'camping/webrick' |
| 215 | | |
| 216 | | # Mount the root |
| 217 | | s = WEBrick::HTTPServer.new(:BindAddress => conf.host, :Port => conf.port) |
| 218 | | if apps.length > 1 |
| 219 | | apps.each do |app| |
| 220 | | s.mount "/#{app.mount}", WEBrick::CampingHandler, app |
| 221 | | s.mount_proc("/code/#{app.mount}") do |req, resp| |
| 222 | | resp['Content-Type'] = 'text/plain' |
| 223 | | resp.body = app.view_source |
| 224 | | end |
| 225 | | end |
| 226 | | s.mount_proc("/") do |req, resp| |
| 227 | | apps.find_new_scripts do |app| |
| 228 | | s.mount "/#{app.mount}", WEBrick::CampingHandler, app |
| 229 | | s.mount_proc("/code/#{app.mount}") do |req, resp| |
| 230 | | resp['Content-Type'] = 'text/plain' |
| 231 | | resp.body = app.view_source |
| 232 | | end |
| 233 | | end |
| 234 | | resp.body = apps.index_page |
| 235 | | end |
| 236 | | else |
| 237 | | s.mount "/", WEBrick::CampingHandler, apps.first |
| 238 | | end |
| 239 | | |
| 240 | | # Server up |
| 241 | | trap(:INT) do |
| 242 | | s.shutdown |
| 243 | | end |
| 244 | | s.start |
| 245 | | when 'lighttpd' |
| 246 | | require 'rbconfig' |
| 247 | | ruby = File.join(Config::CONFIG['bindir'], Config::CONFIG['RUBY_INSTALL_NAME']) |
| 248 | | dispatcher =<<SCRIPT |
| 249 | | #!#{ruby} |
| 250 | | require 'rubygems' |
| 251 | | require 'camping/fastcgi' |
| 252 | | Camping::Models::Base.establish_connection(Marshal.load(#{Marshal.dump(conf.database).dump})) |
| 253 | | Camping::FastCGI.serve("") |
| 254 | | SCRIPT |
| 255 | | lighttpd_conf =<<CONF |
| 256 | | server.port = #{conf.port} |
| 257 | | server.bind = "#{conf.host}" |
| 258 | | server.modules = ( "mod_fastcgi" ) |
| 259 | | server.document-root = "/dont/need/one" |
| 260 | | |
| 261 | | #### fastcgi module |
| 262 | | fastcgi.server = ( "/" => ( |
| 263 | | "localhost" => ( |
| 264 | | "socket" => "/tmp/camping-blog.socket", |
| 265 | | "bin-path" => "#{conf.dispatcher}", |
| 266 | | "check-local" => "disable", |
| 267 | | "max-procs" => 1 ) ) ) |
| 268 | | CONF |
| 269 | | |
| 270 | | when 'console' |
| 271 | | ARGV.clear # Avoid passing args to IRB |
| 272 | | |
| 273 | | require 'irb' |
| 274 | | require 'irb/completion' |
| 275 | | if File.exists? ".irbrc" |
| 276 | | ENV['IRBRC'] = ".irbrc" |
| 277 | | end |
| 278 | | IRB.start |
| 279 | | end |
| | 85 | server = eval("Camping::Server::#{conf.server.to_s.capitalize}.new(conf, paths)") |
| | 86 | server.start |