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.
- 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
|