$:.unshift File.dirname(__FILE__) require 'fileutils' require 'redcloth' require 'source_file_handler' require 'file_processor' module BuildMaster #todo match only beginning of the file TEXTILE_REGX = /---(-)*\n(.*)\n(-)*---/ class NullLogger def << message puts "IGNORED: #{message}" end end class SiteSpec def self.get_instance self.new() end attr_accessor :output_dir, :content_dir, :template, :template_file def validate_inputs validate_dir(@content_dir, :content_dir) end def load_template if (@template) return XTemplate.new(@template) else return XTemplate.new(File.open(@template_file)) end end private def validate_dir(directory, symbol) if not directory raise "Directory for #{symbol.id2name} not specified" end if not File.exists? directory raise "Directory for #{symbol.id2name} -- <#{directory}#> does not exist" end if not File.directory? directory raise "<#{directory}> should be a directory for #{symbol.id2name}" end end def validate_file(file, symbol) if not file raise "File for #{symbol.id2name} not specified" end if (not File.exists? file) raise "File for #{symbol.id2name} -- <#{file}> does not exist" end if not File.file? file raise "#<{file} should be a file for #{symbol.id2name}" end end end class Site def initialize(spec) @spec = spec @spec.validate_inputs @template = @spec.load_template end public def execute(arguments) action = 'build' if arguments.size > 0 action = arguments[0] end method(action).call end def build @count = 0 build_directory(@spec.output_dir, @spec.content_dir, @template) puts "Generated file count: #{@count}" end def server(port_number=2000, log_file=$stdout, level=WEBrick::Log::INFO, access_log=nil) require 'webrick' mime_types = WEBrick::HTTPUtils::DefaultMimeTypes.update( {"textile" => "text/plain"} ) @server = WEBrick::HTTPServer.new( :Port => port_number, :Logger => WEBrick::Log.new(log_file, level), :MimeTypes => mime_types, :AccessLog => access_log ) @server.mount('/', SourceFileHandler, @spec) @server.mount('/source', WEBrick::HTTPServlet::FileHandler, @spec.content_dir, true) ['INT', 'TERM'].each { |signal| trap(signal){ @server.shutdown} } @server.start end def test(port_number=2000) launch_server(port_number) {|port_number| SiteTester.test("http://localhost:#{port_number}")} end def test_offline(port_number=2000) launch_server(port_number) {|port_number| SiteTester.test_offline("http://localhost:#{port_number}")} end private def launch_server(port_number) require 'buildmaster/site_tester' Thread.new() {server(port_number, NullLogger.new, 0, NullLogger.new)} begin yield port_number ensure @server.stop end end def ensure_directory_exists(dir_name) if (not File.exist?(dir_name)) ensure_directory_exists(File.join(dir_name, '..')) Dir.mkdir dir_name end end def build_directory(out_dir, content_dir, template) ensure_directory_exists(out_dir) Dir.foreach(content_dir) do |item| content_path = File.join(content_dir, item) if (item == '.' || item == '..' || item == '.svn' || item == 'CVS') elsif (File.directory? content_path) build_directory(File.join(out_dir, item), content_path, template) else @current_file_name = content_path process_file(content_path, out_dir, content_dir, item) @count = @count + 1 end end end def process_file(content_path, out_dir, content_dir, item) print ">> #{content_path}" extension = File.extname(content_path) isIndex = @current_file_name =~ /^index/ file_processor = FileProcessor.new(@template, content_path, @spec) if (extension.casecmp('.textile') == 0) base_name = File.basename(item, extension) output_file = File.join(out_dir, base_name + '.html') write(output_file, file_processor.process_textile()) elsif (extension.casecmp('.html') == 0) output_file = File.join(out_dir, item) write(output_file, file_processor.process_html()) else output_file = File.join(out_dir, item) puts " ==> #{output_file}" FileUtils.cp content_path, output_file end end def write(target_file, xhtml) puts " ==> #{target_file}" File.open(target_file, "w") do |file| xhtml.write(file, 0, false, true) end end end end