Module: Cheat

Extended by:
Cheat
Included in:
Cheat
Defined in:
lib/cheat.rb,
lib/cheat/diffr.rb,
lib/cheat/version.rb

Defined Under Namespace

Modules: Controllers, Helpers, Models, Views Classes: Diffr

Constant Summary collapse

HOST =
ARGV.include?('debug') ? 'localhost' : 'cheat.errtheblog.com'
PORT =
ARGV.include?('debug') ? 3001 : 80
SUFFIX =
''
VERSION =
"1.3.0"

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.createObject



592
593
594
# File 'lib/cheat/site.rb', line 592

def Cheat.create
  Cheat::Models.create_schema
end

Instance Method Details

#add(title) ⇒ Object



147
148
149
150
151
# File 'lib/cheat.rb', line 147

def add(title)
  body = write_to_tempfile(title)
  res = post_sheet(title, body, true)
  check_errors(res, title, body)
end

#cache_dirObject



187
188
189
# File 'lib/cheat.rb', line 187

def cache_dir
  RUBY_PLATFORM =~ /win32/ ? win32_cache_dir : File.join(File.expand_path("~"), ".cheat")
end

#cache_fileObject



89
90
91
# File 'lib/cheat.rb', line 89

def cache_file
  "#{cache_dir}/#{@sheet}.yml" if cache_dir
end

#cheat_uriObject



97
98
99
# File 'lib/cheat.rb', line 97

def cheat_uri
  "#{HOST}:#{PORT}#{SUFFIX}"
end

#check_errors(result, title, text) ⇒ Object



172
173
174
175
176
177
178
179
180
181
# File 'lib/cheat.rb', line 172

def check_errors(result, title, text)
  if result.body =~ /<p class="error">(.+?)<\/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}"
  end
end

#clear_cacheObject



201
202
203
# File 'lib/cheat.rb', line 201

def clear_cache
  FileUtils.rm_rf(cache_dir) if cache_dir
end

#clear_cache_fileObject



205
206
207
# File 'lib/cheat.rb', line 205

def clear_cache_file
  FileUtils.rm(cache_file) if File.exists?(cache_file) 
end

#diff_sheets(sheet, version) ⇒ Object

$ cheat greader –diff 1



72
73
74
75
76
77
78
79
80
# File 'lib/cheat.rb', line 72

def diff_sheets(sheet, version)
  return unless version =~ /^(\d+)(:(\d+))?$/
  old_version, new_version = $1, $3

  uri = "http://#{cheat_uri}/d/#{sheet}/#{old_version}"
  uri += "/#{new_version}" if new_version

  fetch_sheet(uri, false) 
end

#edit(sheet_yaml) ⇒ Object



138
139
140
141
142
143
144
145
# File 'lib/cheat.rb', line 138

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

#editorObject



183
184
185
# File 'lib/cheat.rb', line 183

def editor
  ENV['VISUAL'] || ENV['EDITOR'] || "vim" 
end

#execute(sheet_yaml) ⇒ Object



101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/cheat.rb', line 101

def execute(sheet_yaml)
  sheet_body = YAML.load(sheet_yaml).to_a.flatten.last
  puts "\n  " + sheet_body.gsub("\r",'').gsub("\n", "\n  ").wrap
  puts "\nWould you like to execute the above sheet? (Y/N)"
  answer = STDIN.gets
  case answer.chomp
  when "Y" then system YAML.load(sheet_yaml).to_a.flatten.last
  when "N" then puts "Not executing sheet."
  else
    puts "Must be Y or N!"
  end
rescue Errno::EPIPE
  # do nothing
rescue
  puts "That didn't work.  Maybe try `$ cheat cheat' for help?" # Fix Emacs ruby-mode highlighting bug: `"
end

#fetch_sheet(uri, try_to_cache = true) ⇒ Object



30
31
32
33
34
35
36
37
38
39
40
# File 'lib/cheat.rb', line 30

def fetch_sheet(uri, try_to_cache = true)
  open(uri, headers) do |body|
    sheet = body.read
    FileUtils.mkdir_p(cache_dir) unless File.exists?(cache_dir)
    File.open(cache_file, 'w') { |f| f.write(sheet) } if try_to_cache && has_content(sheet) && cache_file && !@edit 
    @edit ? edit(sheet) : show(sheet)
  end 
  exit
rescue OpenURI::HTTPError => e
  puts "Whoa, some kind of Internets error!", "=> #{e} from #{uri}"
end

#has_content(sheet) ⇒ Object



82
83
84
85
86
87
# File 'lib/cheat.rb', line 82

def has_content(sheet)
  if sheet.is_a?(String)
    return (sheet.length > 15) && !sheet[0,14].include?("Error!")
  end
  return true
end

#headersObject



93
94
95
# File 'lib/cheat.rb', line 93

def headers
  { 'User-Agent' => 'cheat!', 'Accept' => 'text/yaml' } 
end

#parse_args(args) ⇒ Object



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/cheat.rb', line 42

def parse_args(args)
  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

  if i = args.index('--diff')
    diff_sheets(args.first, args[i+1]) 
  end

  show_versions(args.first) if args.delete('--versions')

  add(args.shift) and return if args.delete('--add')
  incoming_file = true if @edit = args.delete('--edit')
  
  @execute = true if args.delete("--execute") || args.delete("-x")
  @sheet = args.shift

  clear_cache_file if incoming_file
  true
end

#post_sheet(title, body, new = false) ⇒ Object



153
154
155
156
157
# File 'lib/cheat.rb', line 153

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

#process(sheet_yaml) ⇒ Object



118
119
120
121
122
123
124
# File 'lib/cheat.rb', line 118

def process(sheet_yaml)
  if @execute
    execute(sheet_yaml)
  else
    show(sheet_yaml)
  end
end

#run_pagerObject



209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
# File 'lib/cheat.rb', line 209

def run_pager
  return if RUBY_PLATFORM =~ /win32/
  return unless STDOUT.tty?

  read, write = IO.pipe

  unless Kernel.fork # Child process
    STDOUT.reopen(write)
    STDERR.reopen(write) if STDERR.tty?
    read.close
    write.close
    return
  end

  # Parent process, become pager
  STDIN.reopen(read)
  read.close
  write.close

  ENV['LESS'] = 'FSRX' # Don't page if the input is short enough

  # wait until we have input before we start the pager
  Kernel.select [STDIN]
  pager = ENV['PAGER'] || 'less'
  exec pager rescue exec "/bin/sh", "-c", pager
rescue
end

#sheets(args) ⇒ Object



11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# File 'lib/cheat.rb', line 11

def sheets(args)
  args = args.dup

  return unless parse_args(args)

  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, headers) { |body| process(body.read) }
  end

  return process(File.read(cache_file)) if File.exists?(cache_file) rescue clear_cache if cache_file 

  fetch_sheet(uri + @sheet) if @sheet
end

#show(sheet_yaml) ⇒ Object



126
127
128
129
130
131
132
133
134
135
136
# File 'lib/cheat.rb', line 126

def show(sheet_yaml)
  sheet = YAML.load(sheet_yaml).to_a.first
  sheet[-1] = sheet.last.join("\n") if sheet[-1].is_a?(Array)
  run_pager
  puts sheet.first + ':'
  puts '  ' + sheet.last.gsub("\r",'').gsub("\n", "\n  ").wrap
rescue Errno::EPIPE
  # do nothing
rescue
  puts "That didn't work.  Maybe try `$ cheat cheat' for help?" # Fix Emacs ruby-mode highlighting bug: `"
end

#show_versions(sheet) ⇒ Object

$ cheat greader –versions



67
68
69
# File 'lib/cheat.rb', line 67

def show_versions(sheet)
  fetch_sheet("http://#{cheat_uri}/h/#{sheet}/", false)
end

#win32_cache_dirObject



191
192
193
194
195
196
197
198
199
# File 'lib/cheat.rb', line 191

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

#write_to_tempfile(title, body = nil) ⇒ Object



159
160
161
162
163
164
165
166
167
168
169
170
# File 'lib/cheat.rb', line 159

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