wri 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. data/CHANGES +4 -0
  2. data/MANIFEST +60 -0
  3. data/NOTES +3 -0
  4. data/README +49 -0
  5. data/bin/wri +3 -0
  6. data/lib/wri/fastri_service.rb +387 -0
  7. data/lib/wri/public/css/style.css +70 -0
  8. data/lib/wri/public/css/tree_blue/images/collapsable-last.gif +0 -0
  9. data/lib/wri/public/css/tree_blue/images/collapsable.gif +0 -0
  10. data/lib/wri/public/css/tree_blue/images/expandable-last.gif +0 -0
  11. data/lib/wri/public/css/tree_blue/images/expandable.gif +0 -0
  12. data/lib/wri/public/css/tree_blue/images/leaf-last.gif +0 -0
  13. data/lib/wri/public/css/tree_blue/images/leaf.gif +0 -0
  14. data/lib/wri/public/css/tree_blue/images/root.gif +0 -0
  15. data/lib/wri/public/css/tree_blue/images/spacer.gif +0 -0
  16. data/lib/wri/public/css/tree_blue/images/spinner.gif +0 -0
  17. data/lib/wri/public/css/tree_blue/style.css +83 -0
  18. data/lib/wri/public/css/tree_blue2/images/collapsable-last.gif +0 -0
  19. data/lib/wri/public/css/tree_blue2/images/collapsable.gif +0 -0
  20. data/lib/wri/public/css/tree_blue2/images/expandable-last.gif +0 -0
  21. data/lib/wri/public/css/tree_blue2/images/expandable.gif +0 -0
  22. data/lib/wri/public/css/tree_blue2/images/leaf-last.gif +0 -0
  23. data/lib/wri/public/css/tree_blue2/images/leaf.gif +0 -0
  24. data/lib/wri/public/css/tree_blue2/images/root.gif +0 -0
  25. data/lib/wri/public/css/tree_blue2/images/spacer.gif +0 -0
  26. data/lib/wri/public/css/tree_blue2/images/spinner.gif +0 -0
  27. data/lib/wri/public/css/tree_blue2/style.css +83 -0
  28. data/lib/wri/public/css/tree_xp/images/collapsable-last.gif +0 -0
  29. data/lib/wri/public/css/tree_xp/images/collapsable.gif +0 -0
  30. data/lib/wri/public/css/tree_xp/images/expandable-last.gif +0 -0
  31. data/lib/wri/public/css/tree_xp/images/expandable.gif +0 -0
  32. data/lib/wri/public/css/tree_xp/images/leaf-last.gif +0 -0
  33. data/lib/wri/public/css/tree_xp/images/leaf.gif +0 -0
  34. data/lib/wri/public/css/tree_xp/images/root.gif +0 -0
  35. data/lib/wri/public/css/tree_xp/images/spacer.gif +0 -0
  36. data/lib/wri/public/css/tree_xp/images/spinner.gif +0 -0
  37. data/lib/wri/public/css/tree_xp/style.css +83 -0
  38. data/lib/wri/public/img/dir.gif +0 -0
  39. data/lib/wri/public/img/mod.ico +0 -0
  40. data/lib/wri/public/img/ruby_logo.png +0 -0
  41. data/lib/wri/public/js/jquery.js +11 -0
  42. data/lib/wri/public/js/ri.jquery.js +56 -0
  43. data/lib/wri/ri_service.rb +67 -0
  44. data/lib/wri/server.rb +186 -0
  45. data/lib/wri/template.rhtml +60 -0
  46. data/meta/project.yaml +20 -0
  47. data/meta/version +1 -0
  48. metadata +120 -0
data/CHANGES ADDED
@@ -0,0 +1,4 @@
1
+ === 0.1.0 / 2008-03-28
2
+
3
+ * Initial release.
4
+
@@ -0,0 +1,60 @@
1
+ NOTES
2
+ CHANGES
3
+ README
4
+ meta
5
+ meta/project.yaml
6
+ meta/version
7
+ lib
8
+ lib/wri
9
+ lib/wri/ri_service.rb
10
+ lib/wri/fastri_service.rb
11
+ lib/wri/server.rb
12
+ lib/wri/public
13
+ lib/wri/public/img
14
+ lib/wri/public/img/dir.gif
15
+ lib/wri/public/img/mod.ico
16
+ lib/wri/public/img/ruby_logo.png
17
+ lib/wri/public/js
18
+ lib/wri/public/js/ri.jquery.js
19
+ lib/wri/public/js/jquery.js
20
+ lib/wri/public/css
21
+ lib/wri/public/css/tree_blue2
22
+ lib/wri/public/css/tree_blue2/images
23
+ lib/wri/public/css/tree_blue2/images/collapsable.gif
24
+ lib/wri/public/css/tree_blue2/images/spacer.gif
25
+ lib/wri/public/css/tree_blue2/images/leaf.gif
26
+ lib/wri/public/css/tree_blue2/images/expandable.gif
27
+ lib/wri/public/css/tree_blue2/images/collapsable-last.gif
28
+ lib/wri/public/css/tree_blue2/images/expandable-last.gif
29
+ lib/wri/public/css/tree_blue2/images/spinner.gif
30
+ lib/wri/public/css/tree_blue2/images/leaf-last.gif
31
+ lib/wri/public/css/tree_blue2/images/root.gif
32
+ lib/wri/public/css/tree_blue2/style.css
33
+ lib/wri/public/css/tree_xp
34
+ lib/wri/public/css/tree_xp/images
35
+ lib/wri/public/css/tree_xp/images/collapsable.gif
36
+ lib/wri/public/css/tree_xp/images/spacer.gif
37
+ lib/wri/public/css/tree_xp/images/leaf.gif
38
+ lib/wri/public/css/tree_xp/images/expandable.gif
39
+ lib/wri/public/css/tree_xp/images/collapsable-last.gif
40
+ lib/wri/public/css/tree_xp/images/expandable-last.gif
41
+ lib/wri/public/css/tree_xp/images/spinner.gif
42
+ lib/wri/public/css/tree_xp/images/leaf-last.gif
43
+ lib/wri/public/css/tree_xp/images/root.gif
44
+ lib/wri/public/css/tree_xp/style.css
45
+ lib/wri/public/css/tree_blue
46
+ lib/wri/public/css/tree_blue/images
47
+ lib/wri/public/css/tree_blue/images/collapsable.gif
48
+ lib/wri/public/css/tree_blue/images/spacer.gif
49
+ lib/wri/public/css/tree_blue/images/leaf.gif
50
+ lib/wri/public/css/tree_blue/images/expandable.gif
51
+ lib/wri/public/css/tree_blue/images/collapsable-last.gif
52
+ lib/wri/public/css/tree_blue/images/expandable-last.gif
53
+ lib/wri/public/css/tree_blue/images/spinner.gif
54
+ lib/wri/public/css/tree_blue/images/leaf-last.gif
55
+ lib/wri/public/css/tree_blue/images/root.gif
56
+ lib/wri/public/css/tree_blue/style.css
57
+ lib/wri/public/css/style.css
58
+ lib/wri/template.rhtml
59
+ bin
60
+ bin/wri
data/NOTES ADDED
@@ -0,0 +1,3 @@
1
+ This is the initial release of WebRI. While it could
2
+ still use some "fancying-up", it is already quite usable.
3
+
data/README ADDED
@@ -0,0 +1,49 @@
1
+ = Web RI
2
+
3
+ Webrick-based RI browser
4
+
5
+ == Usage
6
+
7
+ WebRI can be used to browse the entire installed object system --eveything
8
+ documented in one of the central RI locations.
9
+
10
+ WebRI can also be used (and this is probably more useful) to browse per-project
11
+ RI documentation. Simply generate the RI docs by navigating to the projects
12
+ root directory and running:
13
+
14
+ rdoc --ri --op "doc/ri" lib
15
+
16
+ Sometimes a package will include a convenience script for generating these.
17
+ Try running 'rake -T', or look for a 'script/' or 'task/' executable that does
18
+ the job. Usually the generated documentation is placed in either ri/ or doc/ri/.
19
+ I will use doc/ri/ in the following example, sicen that is my preference. Adjust
20
+ your directory as needed.
21
+
22
+ Now run:
23
+
24
+ wri doc/ri
25
+
26
+ You will see a Webrick server start up, informing you of the port being used.
27
+
28
+ [2008-03-28 12:11:16] INFO WEBrick 1.3.1
29
+ [2008-03-28 12:11:16] INFO ruby 1.8.6 (2007-06-07) [x86_64-linux]
30
+ [2008-03-28 12:11:21] INFO WEBrick::HTTPServer#start: pid=8870 port=8888
31
+
32
+ In this example we see the port is the default 8888. Simply open your browser and
33
+ navigate to:
34
+
35
+ http://localhost:8888/
36
+
37
+ On the left side of the screen you will see a navigation tree, and the right side
38
+ contans an infromation panel.
39
+
40
+ == Install
41
+
42
+ gem install wri
43
+
44
+ == License
45
+
46
+ WebRI, Copyright (c) 2008 Tiger Ops
47
+
48
+ WebRi is licensed under then terms of Ruby.
49
+
data/bin/wri ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+ require 'wri/ri_service'
3
+
@@ -0,0 +1,387 @@
1
+ #!/usr/bin/env ruby
2
+ # wri: access RI documentation through DRb
3
+ # Copyright (C) 2006 Mauricio Fernandez <mfp@acm.org>
4
+
5
+ require 'wri/server'
6
+
7
+ require 'fastri/util'
8
+ require 'fastri/full_text_index'
9
+
10
+ default_local_mode = File.basename($0)[/^wri/] ? true : false
11
+
12
+ # we bind to 127.0.0.1 by default, because otherwise Ruby will try with
13
+ # 0.0.0.0, which results in a DNS request, adding way too much latency
14
+ options = {
15
+ :addr => "127.0.0.1",
16
+ :format =>
17
+ case RUBY_PLATFORM
18
+ when /win/
19
+ if /darwin|cygwin/ =~ RUBY_PLATFORM
20
+ "ansi"
21
+ else
22
+ "plain"
23
+ end
24
+ else
25
+ "ansi"
26
+ end,
27
+ :width => 72,
28
+ :lookup_order => [
29
+ :exact, :exact_ci, :nested, :nested_ci, :partial, :partial_ci,
30
+ :nested_partial, :nested_partial_ci,
31
+ ],
32
+ :show_matches => false,
33
+ :do_full_text => false,
34
+ :full_text_dir => File.join(FastRI::Util.find_home, ".fastri-fulltext"),
35
+ :use_pager => nil,
36
+ :pager => nil,
37
+ :list_classes => nil,
38
+ :list_methods => nil,
39
+ :extended => false,
40
+ :index_file => File.join(FastRI::Util.find_home, ".fastri-index"),
41
+ :local_mode => default_local_mode,
42
+ :do_second_guess => true,
43
+ :expand_choices => false,
44
+ }
45
+
46
+ override_addr_env = false
47
+
48
+
49
+ # only load optparse if actually needed
50
+ # saves ~0.01-0.04s.
51
+ if (arg = ARGV[0]) && arg[0, 1] == "-" or ARGV.empty?
52
+ require 'optparse'
53
+ optparser = OptionParser.new do |opts|
54
+ opts.version = FastRI::FASTRI_VERSION
55
+ opts.release = FastRI::FASTRI_RELEASE_DATE
56
+ opts.banner = "Usage: #{File.basename($0)} [options] <query>"
57
+
58
+ opts.on("-L", "--local", "Try to use local index instead of DRb service.",
59
+ *[("(default)" if default_local_mode)].compact) do
60
+ options[:local_mode] = true
61
+ end
62
+ opts.on("--index-file=FILE", "Use index file (forces --local mode).",
63
+ "(default: #{options[:index_file]})") do |file|
64
+ options[:index_file] = file
65
+ options[:local_mode] = true
66
+ end
67
+ opts.on("-R", "--remote", "Use DRb service. #{'(default)' unless default_local_mode}") do
68
+ options[:local_mode] = false
69
+ end
70
+ opts.on("-s", "--bind ADDR", "Bind to ADDR for incoming DRb connections.",
71
+ "(default: 127.0.0.1)") do |addr|
72
+ options[:addr] = addr
73
+ override_addr_env = true
74
+ end
75
+
76
+ order_mapping = {
77
+ 'e' => :exact, 'E' => :exact_ci, 'n' => :nested, 'N' => :nested_ci,
78
+ 'p' => :partial, 'P' => :partial_ci, 'x' => :nested_partial,
79
+ 'X' => :nested_partial_ci, 'a' => :anywhere, 'A' => :anywhere_ci,
80
+ 'm' => :namespace_partial, 'M' => :namespace_partial_ci,
81
+ 'f' => :full_partial, 'F' => :full_partial_ci,
82
+ }
83
+ opts.on("-O", "--order ORDER", "Specify lookup order.",
84
+ "(default: eEnNpPxX)", "Uppercase: case-indep.",
85
+ "e:exact n:nested p:partial (completion)",
86
+ "x:nested and partial m:complete namespace",
87
+ "f:complete both class and method",
88
+ "a:match method name anywhere") do |order|
89
+ options[:lookup_order] = order.split(//).map{|x| order_mapping[x]}.compact
90
+ end
91
+
92
+ opts.on("-1", "--exact", "Does not do second guess(exact query).") do
93
+ options[:do_second_guess] = false
94
+ options[:lookup_order] = [ :exact ]
95
+ end
96
+ opts.on("-a", "--all", "Show info for all methods in Multiple choices",
97
+ "(default: don't)") do
98
+ options[:expand_choices] = true
99
+ end
100
+
101
+ opts.on("-e", "--extended", "Show all methods for given namespace.") do
102
+ options[:extended] = true
103
+ options[:use_pager] = true
104
+ options[:format] = "plain"
105
+ end
106
+
107
+ opts.on("--show-matches", "Only show matching entries."){ options[:show_matches] = true }
108
+
109
+ opts.on("--classes", "List all known classes/modules.") do
110
+ options[:use_pager] = true
111
+ options[:list_classes] = true
112
+ end
113
+ opts.on("--methods", "List all known methods.") do
114
+ options[:use_pager] = true
115
+ options[:list_methods] = true
116
+ end
117
+ opts.on("-l", "--list-names", "List all known namespaces/methods.") do
118
+ options[:use_pager] = true
119
+ options[:list_classes] = true
120
+ options[:list_methods] = true
121
+ end
122
+
123
+ opts.on("-S", "--full-text", "Perform full-text search.") do
124
+ options[:do_full_text] = true
125
+ options[:use_pager] = true if options[:use_pager].nil?
126
+ options[:format] = "plain"
127
+ end
128
+
129
+ opts.on("-F", "--full-text-dir DIR", "Use full-text index in DIR",
130
+ "(default: #{options[:full_text_dir]})") do |dir|
131
+ options[:full_text_dir] = dir if dir
132
+ options[:do_full_text] = true
133
+ options[:use_pager] = true
134
+ options[:format] = "plain"
135
+ end
136
+
137
+ opts.on("-f", "--format FMT", "Format to use when displaying output:",
138
+ " ansi, plain (default: #{options[:format]})") do |format|
139
+ options[:format] = format
140
+ end
141
+
142
+ opts.on("-P", "--[no-]pager", "Use pager.", "(default: don't)") do |usepager|
143
+ options[:use_pager] = usepager
144
+ options[:format] = "plain" if usepager
145
+ end
146
+
147
+ opts.on("-T", "Don't use a pager."){ options[:use_pager] = false }
148
+
149
+ opts.on("--pager-cmd PAGER", "Use pager PAGER.", "(default: don't)") do |pager|
150
+ options[:pager] = pager
151
+ options[:use_pager] = true
152
+ options[:format] = "plain"
153
+ end
154
+
155
+ opts.on("-w", "--width WIDTH", "Set the width of the output.") do |width|
156
+ w = width.to_i
157
+ options[:width] = w > 0 ? w : options[:width]
158
+ end
159
+
160
+ opts.on("-h", "--help", "Show this help message") do
161
+ puts opts
162
+ exit
163
+ end
164
+ end
165
+ optparser.parse!
166
+
167
+ #if !options[:list_classes] && !options[:list_methods] && ARGV.empty?
168
+ # puts optparser
169
+ # exit
170
+ #end
171
+ end # lazy optparse loading
172
+
173
+ # {{{ try to find where the method comes from exactly
174
+ include FastRI::Util::MagicHelp
175
+
176
+ MAX_CONTEXT_LINES = 20
177
+ def context_wrap(text, width)
178
+ "... " +
179
+ text.gsub(/(.{1,#{width-4}})( +|$\n?)|(.{1,#{width-4}})/, "\\1\\3\n").chomp
180
+ end
181
+
182
+ def display_fulltext_search_results(results, gem_dir_info = FastRI::Util.gem_directories_unique,
183
+ width = 78)
184
+ return if results.empty?
185
+ path = File.expand_path(results[0].path)
186
+ gem_name, version, gem_path = FastRI::Util.gem_info_for_path(path, gem_dir_info)
187
+ if gem_name
188
+ rel_path = path[/#{Regexp.escape(gem_path)}\/(.*)/, 1]
189
+ if rel_path
190
+ entry_name = FastRI::Util.gem_relpath_to_full_name(rel_path)
191
+ end
192
+ puts "Found in #{gem_name} #{version} #{entry_name}"
193
+ else
194
+ rdoc_system_path = File.expand_path(RI::Paths::SYSDIR)
195
+ if path.index(rdoc_system_path)
196
+ rel_path = path[/#{Regexp.escape(rdoc_system_path)}\/(.*)/, 1]
197
+ puts "Found in system #{FastRI::Util.gem_relpath_to_full_name(rel_path)}"
198
+ else
199
+ puts "Found in #{path}:"
200
+ end
201
+ end
202
+ text = results.map do |result|
203
+ context = result.context(120)
204
+ from = (context.rindex("\n", context.index(result.query)) || -1) + 1
205
+ to = (context.index("\n", context.index(result.query)) || 0) - 1
206
+ context_wrap(context[from..to], width)
207
+ end
208
+ puts
209
+ puts text.uniq[0...MAX_CONTEXT_LINES]
210
+ puts
211
+ end
212
+
213
+ def perform_fulltext_search(options)
214
+ fulltext = File.join(options[:full_text_dir], "full_text.dat")
215
+ suffixes = File.join(options[:full_text_dir], "suffixes.dat")
216
+ begin
217
+ index = FastRI::FullTextIndex.new_from_filenames(fulltext, suffixes)
218
+ rescue Exception
219
+ puts <<EOF
220
+ Couldn't open the full-text index:
221
+ #{fulltext}
222
+ #{suffixes}
223
+
224
+ The index needs to be rebuilt with
225
+ fastri-server -B
226
+ EOF
227
+ exit(-1)
228
+ end
229
+ gem_dir_info = FastRI::Util.gem_directories_unique
230
+ match_sets = ARGV.map do |query|
231
+ result = index.lookup(query)
232
+ if result
233
+ index.next_matches(result) + [result]
234
+ else
235
+ []
236
+ end
237
+ end
238
+ path_map = Hash.new{|h,k| h[k] = []}
239
+ match_sets.each{|matches| matches.each{|m| path_map[m.path] << m} }
240
+ paths = match_sets[1..-1].inject(match_sets[0].map{|x| x.path}.uniq) do |s,x|
241
+ s & x.map{|y| y.path}.uniq
242
+ end
243
+ if paths.empty?
244
+ puts "nil"
245
+ else
246
+ puts "#{paths.size} hits"
247
+ paths.sort_by{|path| 1.0 * -path_map[path].size / path_map[path].first.metadata[:size] ** 0.5}.map do |path|
248
+ puts "=" * options[:width]
249
+ puts 1.0 * path_map[path].size / path_map[path].first.metadata[:size] ** 0.5
250
+ display_fulltext_search_results(path_map[path], gem_dir_info, options[:width])
251
+ end
252
+ end
253
+
254
+ exit 0
255
+ end
256
+
257
+ #{{{ set up pager
258
+ if options[:use_pager]
259
+ [options[:pager], ENV["PAGER"], "less", "more", "pager"].compact.uniq.each do |pager|
260
+ begin
261
+ $stdout = IO.popen(pager, "w")
262
+ at_exit{ $stdout.close }
263
+ break
264
+ rescue Exception
265
+ end
266
+ end
267
+ end
268
+
269
+ #{{{ perform full text search if asked to
270
+ perform_fulltext_search(options) if options[:do_full_text]
271
+
272
+ #{{{ normal query
273
+ if options[:local_mode]
274
+ require 'fastri/ri_service'
275
+ ri_reader = open(options[:index_file], "rb"){|io| Marshal.load io } rescue nil
276
+ unless ri_reader
277
+ puts <<EOF
278
+ Couldn't open the index:
279
+ #{options[:index_file]}
280
+
281
+ The index needs to be rebuilt with
282
+ fastri-server -b
283
+ EOF
284
+ exit(-1)
285
+ end
286
+ service = FastRI::RiService.new(ri_reader)
287
+ else # remote
288
+ require 'rinda/ring'
289
+
290
+ #{{{ determine the address to bind to
291
+ if override_addr_env
292
+ addr_spec = options[:addr]
293
+ else
294
+ addr_spec = ENV["FASTRI_ADDR"] || options[:addr]
295
+ end
296
+
297
+ ip = addr_spec[/^[^:]+/] || "127.0.0.1"
298
+ port = addr_spec[/:(\d+)/, 1] || 0
299
+ addr = "druby://#{ip}:#{port}"
300
+
301
+ #{{{ start DRb and perform request
302
+ begin
303
+ DRb.start_service(addr)
304
+ ring_server = Rinda::RingFinger.primary
305
+ rescue Exception
306
+ $stderr.puts <<EOF
307
+ Couldn't initialize DRb and locate the Ring server.
308
+
309
+ Please make sure that:
310
+ * the fastri-server is running, the server is bound to the correct interface,
311
+ and the ACL setup allows connections from this host
312
+ * fri is using the correct interface for incoming DRb requests:
313
+ either set the FASTRI_ADDR environment variable, or use --bind ADDR, e.g
314
+ export FASTRI_ADDR="192.168.1.12"
315
+ fri Array
316
+ EOF
317
+ exit(-1)
318
+ end
319
+ service = ring_server.read([:name, :FastRI, nil, nil])[2]
320
+ end
321
+
322
+
323
+ info_options = {
324
+ :formatter => options[:format],
325
+ :width => options[:width],
326
+ :lookup_order => options[:lookup_order],
327
+ :extended => options[:extended],
328
+ :expand_choices => options[:expand_choices],
329
+ }
330
+
331
+ =begin
332
+ # {{{ list classes or methods
333
+ puts service.all_classes if options[:list_classes]
334
+ puts service.all_methods if options[:list_methods]
335
+ exit if options[:list_classes] || options[:list_methods]
336
+
337
+ # {{{ normal query
338
+
339
+ ARGV.each do |term|
340
+ help_query = magic_help(term)
341
+ if options[:show_matches]
342
+ puts service.matches(help_query, info_options).sort
343
+ else
344
+ result = service.info(help_query, info_options)
345
+ # second-guess the correct method type only as the last resort.
346
+ if result
347
+ puts result
348
+ elsif options[:do_second_guess] and (new_query = FastRI::Util.change_query_method_type(help_query)) != help_query
349
+ puts service.info(new_query)
350
+ else
351
+ puts nil
352
+ end
353
+ end
354
+ end
355
+ =end
356
+
357
+ wri = WRI::Server.new(service)
358
+ #puts wri.to_html
359
+
360
+ require 'webrick'
361
+ include WEBrick
362
+
363
+ p wri.directory + "/public"
364
+
365
+ s = HTTPServer.new(
366
+ :Port => 8888,
367
+ :DocumentRoot => wri.directory + "/public"
368
+ )
369
+
370
+ s.mount_proc("/index"){|req, res|
371
+ res.body = wri.to_html
372
+ res['Content-Type'] = "text/html"
373
+ }
374
+
375
+ s.mount_proc("/ri"){|req, res|
376
+ res.body = wri.lookup(req)
377
+ res['Content-Type'] = "text/html"
378
+ }
379
+
380
+ ## mount subdirectories
381
+ s.mount("/js", HTTPServlet::FileHandler, wri.directory + "/public/js")
382
+ s.mount("/css", HTTPServlet::FileHandler, wri.directory + "/public/css")
383
+ s.mount("/img", HTTPServlet::FileHandler, wri.directory + "/public/img")
384
+
385
+ trap("INT"){ s.shutdown }
386
+ s.start
387
+