cheat 1.0.2 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. data/README +17 -0
  2. data/lib/cheat.rb +67 -10
  3. data/lib/site.rb +68 -40
  4. metadata +2 -2
data/README CHANGED
@@ -7,6 +7,23 @@ $ cheat sheets
7
7
  $ cheat cheat
8
8
  $ cheat recent
9
9
 
10
+ To freshen your local cache, supply the --new edit.
11
+
12
+ $ cheat sheets --new
13
+
14
+ To edit a cheat sheet, use the --edit switch.
15
+
16
+ $ cheat markaby --edit
17
+
18
+ To add a cheat sheet, use the --add switch.
19
+
20
+ $ cheat readme --add
21
+
22
+ Special Thanks To:
23
+ - Evan Weaver
24
+ - Kevin Marsh
25
+ - Jeremy Apthorp
26
+
10
27
  The Cheat Sheet Repository:
11
28
  - http://cheat.errtheblog.com/
12
29
 
@@ -1,5 +1,5 @@
1
1
  $:.unshift File.dirname(__FILE__)
2
- %w[rubygems fileutils net/http yaml open-uri wrap].each { |f| require f }
2
+ %w[rubygems tempfile fileutils net/http yaml open-uri wrap].each { |f| require f }
3
3
 
4
4
  module Cheat
5
5
  extend self
@@ -11,34 +11,42 @@ module Cheat
11
11
  def sheets(args)
12
12
  args = args.dup
13
13
 
14
- return puts("Looking for help? Try http://cheat.errtheblog.com or `$ cheat cheat'") if args.empty?
14
+ puts "Looking for help? Try http://cheat.errtheblog.com or `$ cheat cheat'" and return if args.empty?
15
15
 
16
- if (i = args.index('--clear-cache') || i = args.index('--new'))
17
- args.delete_at(i)
16
+ if args.delete('--clear-cache') || args.delete('--new')
18
17
  clear_cache
19
18
  return if args.empty?
20
19
  end
21
20
 
21
+ add(args.shift) and return if args.delete('--add')
22
+
23
+ if edit = args.delete('--edit')
24
+ clear_cache
25
+ end
26
+
22
27
  sheet = args.shift
23
28
 
24
29
  cache_file = "#{cache_dir}/#{sheet}.yml" if cache_dir
25
30
  FileUtils.mkdir(cache_dir) unless File.exists?(cache_dir) if cache_dir
26
31
 
27
- host = HOST + ':' + PORT.to_s + SUFFIX
28
- uri = "http://#{host}/y/"
32
+ uri = "http://#{cheat_uri}/y/"
29
33
 
30
34
  if %w[sheets all recent].include? sheet
31
35
  uri = uri.sub('/y/', sheet == 'recent' ? '/yr/' : '/ya/')
32
36
  return open(uri) { |body| show(body.read) }
33
37
  end
34
38
 
35
- return show(File.read(cache_file)) if File.exists?(cache_file) rescue clear_cache if cache_file
39
+ return show(File.read(cache_file)) if File.exists?(cache_file) rescue clear_cache if cache_file
36
40
 
37
41
  open(uri += sheet) do |body|
38
42
  sheet = body.read
39
- File.open(cache_file, 'w') { |f| f.write(sheet) } if cache_file
40
- show(sheet)
41
- end
43
+ File.open(cache_file, 'w') { |f| f.write(sheet) } if cache_file && !edit
44
+ edit ? edit(sheet) : show(sheet)
45
+ end if sheet
46
+ end
47
+
48
+ def cheat_uri
49
+ "#{HOST}:#{PORT}#{SUFFIX}"
42
50
  end
43
51
 
44
52
  def show(sheet_yaml)
@@ -48,6 +56,55 @@ module Cheat
48
56
  puts ' ' + sheet.last.gsub("\r",'').gsub("\n", "\n ").wrap(80)
49
57
  end
50
58
 
59
+ def edit(sheet_yaml)
60
+ sheet = YAML.load(sheet_yaml).to_a.first
61
+ sheet[-1] = sheet.last.gsub("\r", '')
62
+ body, title = write_to_tempfile(*sheet), sheet.first
63
+ return if body.strip == sheet.last.strip
64
+ res = post_sheet(title, body)
65
+ check_errors(res, title, body)
66
+ end
67
+
68
+ def add(title)
69
+ body = write_to_tempfile(title)
70
+ res = post_sheet(title, body, true)
71
+ check_errors(res, title, body)
72
+ end
73
+
74
+ def post_sheet(title, body, new = false)
75
+ uri = "http://#{cheat_uri}/w/"
76
+ uri += title unless new
77
+ Net::HTTP.post_form(URI.parse(uri), "sheet_title" => title, "sheet_body" => body.strip, "from_gem" => true)
78
+ end
79
+
80
+ def write_to_tempfile(title, body = nil)
81
+ # god dammit i hate tempfile, this is so messy but i think it's
82
+ # the only way.
83
+ tempfile = Tempfile.new(title + '.cheat')
84
+ tempfile.write(body) if body
85
+ tempfile.close
86
+ system "#{editor} #{tempfile.path}"
87
+ tempfile.open
88
+ body = tempfile.read
89
+ tempfile.close
90
+ body
91
+ end
92
+
93
+ def check_errors(result, title, text)
94
+ if result.body =~ /<p class="error">(.+?)<\/p>/m
95
+ puts $1.gsub(/\n/, '').gsub(/<.+?>/, '').squeeze(' ').wrap(80)
96
+ puts
97
+ puts "Here's what you wrote, so it isn't lost in the void:"
98
+ puts text
99
+ else
100
+ puts "Success! Try it!", "$ cheat #{title} --new"
101
+ end
102
+ end
103
+
104
+ def editor
105
+ ENV['VISUAL'] || ENV['EDITOR'] || "vim"
106
+ end
107
+
51
108
  def cache_dir
52
109
  PLATFORM =~ /win32/ ? win32_cache_dir : File.join(File.expand_path("~"), ".cheat")
53
110
  end
@@ -21,7 +21,7 @@
21
21
  # Cheat Lake, a nearby resevoir
22
22
  # Cheat Mountain, one of the highest mountains in the Alleghenies
23
23
  #
24
- %w[rubygems camping camping/db erb acts_as_versioned wrap].each { |f| require f }
24
+ %w[rubygems camping camping/db erb open-uri acts_as_versioned wrap].each { |f| require f }
25
25
  require_gem 'camping', '>=1.4.152'
26
26
 
27
27
  Camping.goes :Cheat
@@ -73,8 +73,7 @@ module Cheat::Controllers
73
73
  def get
74
74
  @headers['Content-Type'] = 'text/plain'
75
75
 
76
- fake = Class.new.send(:include, Cheat::Helpers).new
77
- return { 'Recent Cheat Sheets' => fake.recent_sheets.map(&:title) }.to_yaml
76
+ return { 'Recent Cheat Sheets' => Sheet.find(:all, :order => 'created_at DESC', :limit => 15).map(&:title) }.to_yaml
78
77
  end
79
78
  end
80
79
 
@@ -106,16 +105,6 @@ module Cheat::Controllers
106
105
  end
107
106
  end
108
107
 
109
- class Revert < R '/r/(\w+)/(\d+)'
110
- def get(title, version)
111
- current = Sheet.find_by_title(title)
112
- old = current.find_version(version)
113
- current.title, current.body = old.title, old.body
114
- current.save
115
- redirect "#{URL}/s/#{title}"
116
- end
117
- end
118
-
119
108
  class Edit < R '/e/(\w+)/(\d+)', '/e/(\w+)'
120
109
  def get(title, version = nil)
121
110
  @sheet = Sheet.find_by_title(title)
@@ -136,6 +125,10 @@ module Cheat::Controllers
136
125
 
137
126
  @error = input.sheet_body =~ /<a\s*href=/
138
127
 
128
+ unless input.from_gem
129
+ @error = true unless captcha_pass?(input.chunky, input.bacon)
130
+ end
131
+
139
132
  if !@error && @sheet.update_attributes(:title => input.sheet_title,
140
133
  :body => input.sheet_body)
141
134
  redirect "#{URL}/s/#{@sheet.title}"
@@ -144,20 +137,33 @@ module Cheat::Controllers
144
137
  render title ? :edit : :add
145
138
  end
146
139
  end
140
+
141
+ def captcha_pass?(session, answer)
142
+ open("http://captchator.ruby-forum.com/captcha/check_answer/#{session}/#{answer}").read.to_i.nonzero? rescue false
143
+ end
147
144
  end
148
145
 
149
146
  class Browse < R '/b'
150
147
  def get
151
- @sheets = Sheet.find(:all, :order => 'created_at DESC')
148
+ @sheets = Sheet.find(:all, :order => 'title ASC')
152
149
  render :browse
153
150
  end
154
151
  end
155
152
 
156
- class Show < R '/s/(\w+)', '/s/(\w+)/(\d+)'
153
+ class Show < R '/s/(\w+)', '/s/(\w+)/(\d+)', '/s/(\w+\.txt)'
157
154
  def get(title, version = nil)
155
+ # fake respond_to
156
+ if title =~ /\.txt/ && title.sub!('.txt', '').size
157
+ text = true
158
+ @headers['Content-Type'] = 'text/plain'
159
+ end
160
+
158
161
  @sheet = Sheet.find_by_title(title)
159
162
  @sheet = @sheet.find_version(version) if version && @sheet
160
- if @sheet
163
+
164
+ if @sheet && text
165
+ return @sheet.body
166
+ elsif @sheet
161
167
  render :show
162
168
  else
163
169
  redirect "#{URL}/b/"
@@ -178,12 +184,11 @@ module Cheat::Views
178
184
  html {
179
185
  head {
180
186
  _style
181
- link :href => FEED, :rel => "alternate", :title => "Recent Cheat Sheets", :type => "application/atom+xml"
187
+ link :href => FEED, :rel => "alternate", :title => "Recently Updated Cheat Sheets", :type => "application/atom+xml"
182
188
  title defined?(@page_title) ? "$ cheat #{@page_title}" : \
183
189
  "$ command line ruby cheat sheets"
184
190
  }
185
191
  body {
186
- #code "Hi this is defunkt. I'm messing around right now (8-9pm pst). Things will get normal soon. thx."
187
192
  div.main {
188
193
  div.header {
189
194
  h1 { logo_link 'cheat sheets.' }
@@ -209,7 +214,6 @@ module Cheat::Views
209
214
  def show
210
215
  @page_title = @sheet.title
211
216
  @sheet_title = @sheet.title
212
- #div.sheet { text h(sheet.body).gsub(/\n(\s+)/, '<br/>' + '&nbsp;' * '\1'.size).gsub(/\r/,'').gsub(/\n/,'<br/>') }
213
217
  pre.sheet { text h(sheet.body.wrap(80)) }
214
218
  div.version {
215
219
  text "Version "
@@ -227,10 +231,14 @@ module Cheat::Views
227
231
  a "history", :href => R(History, @sheet.title)
228
232
  end
229
233
  if @sheet.version != (current = current_sheet).version
234
+ text " | "
235
+ a "revert to", :href => R(Edit, @sheet.title, @sheet.version)
230
236
  text " | "
231
- a "revert to", :href => R(Revert, @sheet.title, @sheet.version)
232
- text " | "
233
- a "current", :href => R(Show, @sheet.title, current.version)
237
+ a "current", :href => R(Show, @sheet.title)
238
+ end
239
+ if @sheet.version == current_sheet.version
240
+ text " | "
241
+ a "text", :href => R(Show, @sheet.title + '.txt')
234
242
  end
235
243
  text " )"
236
244
  }
@@ -284,7 +292,7 @@ module Cheat::Views
284
292
  end
285
293
 
286
294
  def _form
287
- if (@error = @error)
295
+ if @error
288
296
  p.error {
289
297
  strong "HEY! "
290
298
  text "Something is wrong! You can't give your cheat sheet the same name
@@ -300,10 +308,15 @@ module Cheat::Views
300
308
  :type => 'text'
301
309
  small " [ no_spaces_alphanumeric_only ]"
302
310
  }
303
- p {
304
- text 'Cheat Sheet:'
305
- br
306
- textarea @sheet.body, :name => 'sheet_body', :cols => 80, :rows => 30
311
+ p {
312
+ text 'Cheat Sheet:'
313
+ br
314
+ textarea @sheet.body, :name => 'sheet_body', :cols => 80, :rows => 30
315
+ random = rand(10_000)
316
+ br
317
+ img :src => "http://captchator.ruby-forum.com/captcha/image/#{random}"
318
+ input :name => 'chunky', :type => 'hidden', :value => random
319
+ input :name => 'bacon', :size => 10, :type => 'text'
307
320
  }
308
321
  }
309
322
  p "Your cheat sheet will be editable (fixable) by anyone. Each cheat
@@ -324,7 +337,7 @@ module Cheat::Views
324
337
  text "."
325
338
  }
326
339
  p "Get started:"
327
- code "$ sudo gem install cheat --source require.errtheblog.com"
340
+ code "$ sudo gem install cheat"
328
341
  br
329
342
  code "$ cheat strftime"
330
343
  p "A magnificent cheat sheet for Ruby's strftime method will be printed to
@@ -357,12 +370,12 @@ module Cheat::Views
357
370
  xml.instruct!
358
371
  xml.feed "xmlns"=>"http://www.w3.org/2005/Atom" do
359
372
 
360
- xml.title "Recent Cheat Sheets"
373
+ xml.title "Recently Updated Cheat Sheets"
361
374
  xml.id URL + '/'
362
375
  xml.link "rel" => "self", "href" => FEED
363
376
 
364
- sheets = Cheat::Models::Sheet.find(:all, :order => 'created_at DESC', :limit => 30)
365
- xml.updated sheets.first.created_at.xmlschema
377
+ sheets = Cheat::Models::Sheet.find(:all, :order => 'updated_at DESC', :limit => 20)
378
+ xml.updated sheets.first.updated_at.xmlschema
366
379
 
367
380
  sheets.each do |sheet|
368
381
  xml.entry do
@@ -372,6 +385,9 @@ module Cheat::Views
372
385
  xml.updated sheet.updated_at.xmlschema
373
386
  xml.link "rel" => "alternate", "href" => URL + '/s/' + sheet.title
374
387
  xml.summary "A cheat sheet about #{sheet.title}. Run it: `$ cheat #{sheet.title}'"
388
+ xml.content 'type' => 'html' do
389
+ xml.text! sheet.body.gsub("\n", '<br/>').gsub("\r", '')
390
+ end
375
391
  end
376
392
  end
377
393
  end
@@ -379,15 +395,15 @@ module Cheat::Views
379
395
 
380
396
  def _side
381
397
  text '( '
382
- a 'add', :href => R(Add)
398
+ a 'add new', :href => R(Add)
383
399
  text ' | '
384
- a 'browse', :href => R(Browse)
400
+ a 'see all', :href => R(Browse)
385
401
  text ' )'
386
402
  ul {
387
- li { strong "recent cheat sheets" }
403
+ li { strong "updated sheets" }
388
404
  li do
389
405
  a :href => FEED do
390
- img(:alt => "Recent Cheat Sheets Feed", :src => "http://errtheblog.com/images/theme/feed.png")
406
+ img(:border => 0, :alt => "Recently Updated Cheat Sheets Feed", :src => "http://errtheblog.com/images/theme/feed.png")
391
407
  end
392
408
  end
393
409
  recent_sheets.each do |sheet|
@@ -414,7 +430,7 @@ module Cheat::Views
414
430
  dash = hover
415
431
  version = "#fcf095"
416
432
  style :type => "text/css" do
417
- text %{
433
+ text %[
418
434
  body { font-family: verdana, sans-serif; background-color: #{bg};
419
435
  line-height: 20px; }
420
436
  a:link, a:visited { color: #{link}; }
@@ -424,6 +440,7 @@ module Cheat::Views
424
440
  background-color: #{version}; }
425
441
  h1 { font-size: 5em; margin: 0; padding-left: 30px; color: #{h1};
426
442
  clear: both; font-weight: bold; letter-spacing: -5px; }
443
+ h1 a { text-decoration: none; }
427
444
  div.main { float: left; width: 100%; }
428
445
  div.content { float: left; width: 70%; padding: 15px 0 15px 30px;
429
446
  line-height: 20px; }
@@ -442,7 +459,14 @@ module Cheat::Views
442
459
  div.clear_10 { clear: both; font-size: 10px; line-height: 10px; }
443
460
  textarea { font-family: courier; }
444
461
  code { background-color: #{version} }
445
- }.gsub(/(\s{2,})/, '').gsub("\n", '')
462
+ @media print {
463
+ .side, .version, .footer { display: none; }
464
+ div.content { width: 100%; }
465
+ h1 a:link, h1 a:visited { color: #eee;}
466
+ .header code { font-size: 18px; background: none; }
467
+ div.header { border-bottom: none; }
468
+ }
469
+ ].gsub(/(\s{2,})/, '').gsub("\n", '')
446
470
  end
447
471
  end
448
472
  end
@@ -451,7 +475,7 @@ module Cheat::Helpers
451
475
  def logo_link(title)
452
476
  ctr = Cheat::Controllers
453
477
  if @sheet && !@sheet.new_record? && @sheet.version != current_sheet.version
454
- a title, :href => R(ctr::Show, @sheet.title, current_sheet.version)
478
+ a title, :href => R(ctr::Show, @sheet.title)
455
479
  else
456
480
  a title, :href => R(ctr::Index)
457
481
  end
@@ -462,7 +486,7 @@ module Cheat::Helpers
462
486
  end
463
487
 
464
488
  def recent_sheets
465
- Cheat::Models::Sheet.find(:all, :order => 'created_at DESC', :limit => 10)
489
+ Cheat::Models::Sheet.find(:all, :order => 'updated_at DESC', :limit => 15)
466
490
  end
467
491
 
468
492
  def sheet_link(title, version = nil)
@@ -485,9 +509,13 @@ module Cheat::Helpers
485
509
  end
486
510
  end
487
511
 
488
- def h(text)
512
+ def self.h(text)
489
513
  ERB::Util::h(text)
490
514
  end
515
+
516
+ def h(text)
517
+ ::Cheat::Helpers.h(text)
518
+ end
491
519
  end
492
520
 
493
521
  def Cheat.create
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.0
3
3
  specification_version: 1
4
4
  name: cheat
5
5
  version: !ruby/object:Gem::Version
6
- version: 1.0.2
7
- date: 2006-09-03 00:00:00 -07:00
6
+ version: 1.1.0
7
+ date: 2006-10-15 00:00:00 -07:00
8
8
  summary: Cheat is a simple command line utility reference program.
9
9
  require_paths:
10
10
  - lib