require 'optparse' require 'rack' require 'rack/showexceptions' require 'rack/commonlogger' require 'rack/lint' module TableSetter class Command BANNER = <<-EOB table-setter is a Sinatra application for rendering and processing CSVs from google docs into HTML. Usage: table-setter COMMAND path/to/table-setter/assets OPTIONS commands: start run the development server, for deployment use config.ru install copy the table-setter assets into the the directory build statically build tables in the ./out/ directory options: EOB def initialize @prefix = "" parse_options @prefix = "/#{@prefix}/".gsub(/^\/\//, "/") command = ARGV.shift @directory = ARGV.shift || '.' TableSetter.configure @directory case command when 'start' then start_server when 'install' then install_assets when 'build' then build_out else puts BANNER end end def start_server app = build_rack Rack::Handler::Thin.run app, :Port => "3000" end def install_assets FileUtils.mkdir_p @directory unless File.exists? @directory puts "\nInstalling TableSetter files...\n\n" base_files.each do |path| copy_file path, File.join(TableSetter.config_path, path.gsub(ROOT + "/template/", "/")) end end def build_out @out_dir = File.join(TableSetter.config_path, 'out', @prefix) puts "\nBuilding your TableSetter files...\n\n" app = build_rack @request = Rack::MockRequest.new(app) build_index build_assets build_tables end private # Option parsing def parse_options @options = {} @option_parser = OptionParser.new do |opts| opts.on "-p", "--prefix PREFIX", "url prefix for the export command" do |prefix| @prefix = "#{prefix}" end end @option_parser.banner = BANNER @option_parser.parse! ARGV end def build_rack prefix = @prefix config = File.join(TableSetter.config_path, "config.ru") Rack::Builder.app do map prefix do if(::File.exists? config) run Rack::Builder.parse_file(config).first else use Rack::CommonLogger, STDERR use Rack::ShowExceptions use Rack::Lint run TableSetter::App end end end end def build_index build_file("#{@prefix}", "index.html") end def build_assets Dir[TableSetter.config_path + "/public/**/*"].each do |path| copy_file path, File.join(path.gsub(TableSetter.config_path + "/public/", "#{@out_dir}/")) end end def build_file(url, out) response = @request.get(url) if response.errors.length > 0 puts "ERROR on #{url}:\n#{response.errors}" and exit 1 end install_file(response.body, File.join(@out_dir, out)) end def build_tables TableSetter::Table.all.each do |table| next if !table.live puts "Building #{table.slug}" build_file("#{@prefix}#{table.slug}/", File.join(table.slug, "index.html")) if table.hard_paginate? table.load (1..table.total_pages).each do |page| puts "Building #{table.slug} #{page} of #{table.total_pages}" build_file("#{@prefix}#{table.slug}/#{page}/", File.join(table.slug, page.to_s, "index.html")) end end end end def base_files Dir[ROOT + "/template/**/*"] end def copy_file(source, dest) ensure_directory dest exists = File.exists? dest FileUtils.cp_r(source, dest) unless exists puts "#{exists ? "exists" : "created"}\t#{dest}" end def ensure_directory(dest) expanded_path = File.dirname dest FileUtils.mkdir_p(expanded_path) unless File.exists?(expanded_path) end def install_file(body, dest) ensure_directory dest body.force_encoding("UTF-8") if RUBY_VERSION > "1.9" File.open(dest, "w") do |file| file.write(body) end end end end