cheat 1.0.2 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
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