$:.unshift File.dirname(__FILE__) %w[rubygems tempfile fileutils net/http yaml open-uri wrap].each { |f| require f } module Cheat extend self HOST = 'cheat.errtheblog.com' PORT = 80 SUFFIX = '' def sheets(args) args = args.dup puts "Looking for help? Try http://cheat.errtheblog.com or `$ cheat cheat'" and return if args.empty? if args.delete('--clear-cache') || args.delete('--new') clear_cache return if args.empty? end add(args.shift) and return if args.delete('--add') if edit = args.delete('--edit') clear_cache end sheet = args.shift cache_file = "#{cache_dir}/#{sheet}.yml" if cache_dir FileUtils.mkdir(cache_dir) unless File.exists?(cache_dir) if cache_dir uri = "http://#{cheat_uri}/y/" if %w[sheets all recent].include? sheet uri = uri.sub('/y/', sheet == 'recent' ? '/yr/' : '/ya/') return open(uri) { |body| show(body.read) } end return show(File.read(cache_file)) if File.exists?(cache_file) rescue clear_cache if cache_file open(uri += sheet) do |body| sheet = body.read File.open(cache_file, 'w') { |f| f.write(sheet) } if cache_file && !edit edit ? edit(sheet) : show(sheet) end if sheet end def cheat_uri "#{HOST}:#{PORT}#{SUFFIX}" end def show(sheet_yaml) sheet = YAML.load(sheet_yaml).to_a.first sheet[-1] = sheet.last.join("\n") if sheet[-1].is_a?(Array) puts sheet.first + ':' puts ' ' + sheet.last.gsub("\r",'').gsub("\n", "\n ").wrap(80) end def edit(sheet_yaml) sheet = YAML.load(sheet_yaml).to_a.first sheet[-1] = sheet.last.gsub("\r", '') body, title = write_to_tempfile(*sheet), sheet.first return if body.strip == sheet.last.strip res = post_sheet(title, body) check_errors(res, title, body) end def add(title) body = write_to_tempfile(title) res = post_sheet(title, body, true) check_errors(res, title, body) end def post_sheet(title, body, new = false) uri = "http://#{cheat_uri}/w/" uri += title unless new Net::HTTP.post_form(URI.parse(uri), "sheet_title" => title, "sheet_body" => body.strip, "from_gem" => true) end def write_to_tempfile(title, body = nil) # god dammit i hate tempfile, this is so messy but i think it's # the only way. tempfile = Tempfile.new(title + '.cheat') tempfile.write(body) if body tempfile.close system "#{editor} #{tempfile.path}" tempfile.open body = tempfile.read tempfile.close body end def check_errors(result, title, text) if result.body =~ /

(.+?)<\/p>/m puts $1.gsub(/\n/, '').gsub(/<.+?>/, '').squeeze(' ').wrap(80) puts puts "Here's what you wrote, so it isn't lost in the void:" puts text else puts "Success! Try it!", "$ cheat #{title} --new" end end def editor ENV['VISUAL'] || ENV['EDITOR'] || "vim" end def cache_dir PLATFORM =~ /win32/ ? win32_cache_dir : File.join(File.expand_path("~"), ".cheat") end def win32_cache_dir unless File.exists?(home = ENV['HOMEDRIVE'] + ENV['HOMEPATH']) puts "No HOMEDRIVE or HOMEPATH environment variable. Set one to save a" + "local cache of cheat sheets." return false else return File.join(home, 'Cheat') end end def clear_cache FileUtils.rm_rf(cache_dir) if cache_dir end end Cheat.sheets(ARGV) if __FILE__ == $0