wri 0.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 (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
+