cheat 1.0.2 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README +17 -0
- data/lib/cheat.rb +67 -10
- data/lib/site.rb +68 -40
- 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
|
|
data/lib/cheat.rb
CHANGED
@@ -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
|
-
|
14
|
+
puts "Looking for help? Try http://cheat.errtheblog.com or `$ cheat cheat'" and return if args.empty?
|
15
15
|
|
16
|
-
if
|
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
|
-
|
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
|
data/lib/site.rb
CHANGED
@@ -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
|
-
|
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 => '
|
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
|
-
|
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 => "
|
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/>' + ' ' * '\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 "
|
232
|
-
|
233
|
-
|
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
|
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
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
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
|
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 "
|
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 => '
|
365
|
-
xml.updated sheets.first.
|
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 '
|
400
|
+
a 'see all', :href => R(Browse)
|
385
401
|
text ' )'
|
386
402
|
ul {
|
387
|
-
li { strong "
|
403
|
+
li { strong "updated sheets" }
|
388
404
|
li do
|
389
405
|
a :href => FEED do
|
390
|
-
img(:alt => "
|
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
|
-
|
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
|
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 => '
|
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
|
7
|
-
date: 2006-
|
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
|