gonzui 1.2-x86-mswin32-60
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/AUTHORS.txt +9 -0
- data/History.txt +5539 -0
- data/Manifest.txt +115 -0
- data/PostInstall.txt +17 -0
- data/README.rdoc +149 -0
- data/Rakefile +28 -0
- data/bin/gonzui-db +167 -0
- data/bin/gonzui-import +177 -0
- data/bin/gonzui-remove +58 -0
- data/bin/gonzui-search +68 -0
- data/bin/gonzui-server +176 -0
- data/bin/gonzui-update +53 -0
- data/data/gonzui/catalog/catalog.ja +80 -0
- data/data/gonzui/doc/favicon.ico +0 -0
- data/data/gonzui/doc/folder.png +0 -0
- data/data/gonzui/doc/gonzui.css +279 -0
- data/data/gonzui/doc/gonzui.js +111 -0
- data/data/gonzui/doc/text.png +0 -0
- data/data/gonzuirc.sample +29 -0
- data/ext/autopack/autopack.c +88 -0
- data/ext/autopack/extconf.rb +3 -0
- data/ext/delta/delta.c +147 -0
- data/ext/delta/extconf.rb +5 -0
- data/ext/texttokenizer/extconf.rb +5 -0
- data/ext/texttokenizer/texttokenizer.c +93 -0
- data/ext/xmlformatter/extconf.rb +5 -0
- data/ext/xmlformatter/xmlformatter.c +207 -0
- data/lib/gonzui.rb +59 -0
- data/lib/gonzui/apt.rb +193 -0
- data/lib/gonzui/autopack.so +0 -0
- data/lib/gonzui/bdbdbm.rb +118 -0
- data/lib/gonzui/cmdapp.rb +14 -0
- data/lib/gonzui/cmdapp/app.rb +175 -0
- data/lib/gonzui/cmdapp/search.rb +134 -0
- data/lib/gonzui/config.rb +117 -0
- data/lib/gonzui/content.rb +19 -0
- data/lib/gonzui/dbm.rb +673 -0
- data/lib/gonzui/deindexer.rb +162 -0
- data/lib/gonzui/delta.rb +49 -0
- data/lib/gonzui/delta.so +0 -0
- data/lib/gonzui/extractor.rb +347 -0
- data/lib/gonzui/fetcher.rb +309 -0
- data/lib/gonzui/gettext.rb +144 -0
- data/lib/gonzui/importer.rb +84 -0
- data/lib/gonzui/indexer.rb +316 -0
- data/lib/gonzui/info.rb +80 -0
- data/lib/gonzui/license.rb +100 -0
- data/lib/gonzui/logger.rb +48 -0
- data/lib/gonzui/monitor.rb +177 -0
- data/lib/gonzui/progressbar.rb +235 -0
- data/lib/gonzui/remover.rb +38 -0
- data/lib/gonzui/searcher.rb +330 -0
- data/lib/gonzui/searchquery.rb +235 -0
- data/lib/gonzui/searchresult.rb +111 -0
- data/lib/gonzui/texttokenizer.so +0 -0
- data/lib/gonzui/updater.rb +254 -0
- data/lib/gonzui/util.rb +415 -0
- data/lib/gonzui/vcs.rb +128 -0
- data/lib/gonzui/webapp.rb +25 -0
- data/lib/gonzui/webapp/advsearch.rb +123 -0
- data/lib/gonzui/webapp/filehandler.rb +24 -0
- data/lib/gonzui/webapp/jsfeed.rb +61 -0
- data/lib/gonzui/webapp/markup.rb +445 -0
- data/lib/gonzui/webapp/search.rb +269 -0
- data/lib/gonzui/webapp/servlet.rb +319 -0
- data/lib/gonzui/webapp/snippet.rb +155 -0
- data/lib/gonzui/webapp/source.rb +37 -0
- data/lib/gonzui/webapp/stat.rb +137 -0
- data/lib/gonzui/webapp/top.rb +63 -0
- data/lib/gonzui/webapp/uri.rb +140 -0
- data/lib/gonzui/webapp/webrick.rb +48 -0
- data/lib/gonzui/webapp/xmlformatter.so +0 -0
- data/script/console +10 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/script/makemanifest.rb +21 -0
- data/tasks/extconf.rake +13 -0
- data/tasks/extconf/autopack.rake +43 -0
- data/tasks/extconf/delta.rake +43 -0
- data/tasks/extconf/texttokenizer.rake +43 -0
- data/tasks/extconf/xmlformatter.rake +43 -0
- data/test/_external_tools.rb +13 -0
- data/test/_test-util.rb +142 -0
- data/test/foo/Makefile.foo +66 -0
- data/test/foo/bar.c +5 -0
- data/test/foo/bar.h +6 -0
- data/test/foo/foo.c +25 -0
- data/test/foo/foo.spec +33 -0
- data/test/test_apt.rb +42 -0
- data/test/test_autopack_extn.rb +7 -0
- data/test/test_bdbdbm.rb +79 -0
- data/test/test_cmdapp-app.rb +35 -0
- data/test/test_cmdapp-search.rb +99 -0
- data/test/test_config.rb +28 -0
- data/test/test_content.rb +15 -0
- data/test/test_dbm.rb +171 -0
- data/test/test_deindexer.rb +50 -0
- data/test/test_delta.rb +66 -0
- data/test/test_extractor.rb +78 -0
- data/test/test_fetcher.rb +75 -0
- data/test/test_gettext.rb +50 -0
- data/test/test_gonzui.rb +11 -0
- data/test/test_helper.rb +10 -0
- data/test/test_importer.rb +56 -0
- data/test/test_indexer.rb +37 -0
- data/test/test_info.rb +82 -0
- data/test/test_license.rb +49 -0
- data/test/test_logger.rb +60 -0
- data/test/test_monitor.rb +23 -0
- data/test/test_searcher.rb +37 -0
- data/test/test_searchquery.rb +27 -0
- data/test/test_searchresult.rb +43 -0
- data/test/test_texttokenizer.rb +47 -0
- data/test/test_updater.rb +95 -0
- data/test/test_util.rb +149 -0
- data/test/test_vcs.rb +61 -0
- data/test/test_webapp-markup.rb +42 -0
- data/test/test_webapp-util.rb +19 -0
- data/test/test_webapp-xmlformatter.rb +19 -0
- metadata +292 -0
data/lib/gonzui/vcs.rb
ADDED
@@ -0,0 +1,128 @@
|
|
1
|
+
#
|
2
|
+
# vcs.rb - simple interface to version control systems
|
3
|
+
#
|
4
|
+
# Copyright (C) 2004-2005 Satoru Takabayashi <satoru@namazu.org>
|
5
|
+
# All rights reserved.
|
6
|
+
# This is free software with ABSOLUTELY NO WARRANTY.
|
7
|
+
#
|
8
|
+
# You can redistribute it and/or modify it under the terms of
|
9
|
+
# the GNU General Public License version 2.
|
10
|
+
#
|
11
|
+
|
12
|
+
module Gonzui
|
13
|
+
class VCSError < GonzuiError; end
|
14
|
+
|
15
|
+
class AbstractVCS
|
16
|
+
include Util
|
17
|
+
|
18
|
+
def initialize(config, root, mozule)
|
19
|
+
@config = config
|
20
|
+
@root = root
|
21
|
+
@mozule = mozule
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
def run_command(command_line, message)
|
26
|
+
printf("running %s...\n", message) unless @config.quiet
|
27
|
+
dn = "/dev/null"
|
28
|
+
dn = "nul" if (/mswin|mingw|bccwin/ =~ RUBY_PLATFORM)
|
29
|
+
command_line += ">#{dn} 2>&1" unless @config.verbose
|
30
|
+
status = system(command_line)
|
31
|
+
raise VCSError.new("command execution failed") if status == false
|
32
|
+
end
|
33
|
+
|
34
|
+
public
|
35
|
+
def extract
|
36
|
+
File.mkpath(@config.cache_directory)
|
37
|
+
output_directory = File.join(@config.cache_directory, @mozule)
|
38
|
+
if not File.exist?(output_directory)
|
39
|
+
do_checkout(output_directory)
|
40
|
+
elsif File.directory?(output_directory)
|
41
|
+
do_update(output_directory)
|
42
|
+
else
|
43
|
+
raise VCSError.new("#{output_directory}: obstacle found")
|
44
|
+
end
|
45
|
+
return output_directory
|
46
|
+
end
|
47
|
+
|
48
|
+
def clean
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
class CVS < AbstractVCS
|
53
|
+
def initialize(config, root, mozule)
|
54
|
+
require_command("cvs")
|
55
|
+
super(config, root, mozule)
|
56
|
+
end
|
57
|
+
|
58
|
+
def do_checkout(output_directory)
|
59
|
+
Dir.chdir(@config.cache_directory) {
|
60
|
+
command_line = sprintf("cvs -z3 -d %s co -P %s",
|
61
|
+
shell_escape(@root),
|
62
|
+
shell_escape(@mozule))
|
63
|
+
run_command(command_line, "cvs checkout")
|
64
|
+
}
|
65
|
+
end
|
66
|
+
|
67
|
+
def do_update(output_directory)
|
68
|
+
Dir.chdir(output_directory) {
|
69
|
+
run_command("cvs -z3 update -dP", "cvs update")
|
70
|
+
}
|
71
|
+
end
|
72
|
+
|
73
|
+
def do_extract
|
74
|
+
File.mkpath(@config.cache_directory)
|
75
|
+
output_directory = File.join(@config.cache_directory, @mozule)
|
76
|
+
if File.exist?(output_directory)
|
77
|
+
run_cvs_update(output_directory)
|
78
|
+
else
|
79
|
+
run_cvs_checkout
|
80
|
+
end
|
81
|
+
return output_directory
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
class Subversion < AbstractVCS
|
86
|
+
def initialize(config, root, mozule)
|
87
|
+
require_command("svn")
|
88
|
+
super(config, root, mozule)
|
89
|
+
end
|
90
|
+
|
91
|
+
def do_checkout(output_directory)
|
92
|
+
Dir.chdir(@config.cache_directory) {
|
93
|
+
command_line = sprintf("svn co %s %s",
|
94
|
+
shell_escape(@root),
|
95
|
+
shell_escape(@mozule))
|
96
|
+
run_command(command_line, "svn checkout")
|
97
|
+
}
|
98
|
+
end
|
99
|
+
|
100
|
+
def do_update(output_directory)
|
101
|
+
Dir.chdir(output_directory) {
|
102
|
+
run_command("svn update","svn update")
|
103
|
+
}
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
class Git < AbstractVCS
|
108
|
+
def initialize(config, root, mozule = nil)
|
109
|
+
require_command("git")
|
110
|
+
mozule = File.basename(URI.parse(root).path, ".git") unless mozule
|
111
|
+
super(config, root, mozule)
|
112
|
+
end
|
113
|
+
|
114
|
+
def do_checkout(output_directory)
|
115
|
+
Dir.chdir(@config.cache_directory) {
|
116
|
+
command_line = sprintf("git clone %s",
|
117
|
+
shell_escape(@root))
|
118
|
+
run_command(command_line, "git clone")
|
119
|
+
}
|
120
|
+
end
|
121
|
+
|
122
|
+
def do_update(output_directory)
|
123
|
+
Dir.chdir(output_directory) {
|
124
|
+
run_command("git pull","git pull")
|
125
|
+
}
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
#
|
2
|
+
# webapp.rb - a library for web-based applications
|
3
|
+
#
|
4
|
+
# Copyright (C) 2004-2005 Satoru Takabayashi <satoru@namazu.org>
|
5
|
+
# All rights reserved.
|
6
|
+
# This is free software with ABSOLUTELY NO WARRANTY.
|
7
|
+
#
|
8
|
+
# You can redistribute it and/or modify it under the terms of
|
9
|
+
# the GNU General Public License version 2.
|
10
|
+
#
|
11
|
+
|
12
|
+
require 'gonzui/webapp/xmlformatter'
|
13
|
+
require 'gonzui/webapp/webrick'
|
14
|
+
require 'gonzui/webapp/uri'
|
15
|
+
require 'gonzui/webapp/servlet'
|
16
|
+
require 'gonzui/webapp/snippet'
|
17
|
+
|
18
|
+
require 'gonzui/webapp/advsearch'
|
19
|
+
require 'gonzui/webapp/filehandler'
|
20
|
+
require 'gonzui/webapp/jsfeed'
|
21
|
+
require 'gonzui/webapp/markup'
|
22
|
+
require 'gonzui/webapp/search'
|
23
|
+
require 'gonzui/webapp/source'
|
24
|
+
require 'gonzui/webapp/stat'
|
25
|
+
require 'gonzui/webapp/top'
|
@@ -0,0 +1,123 @@
|
|
1
|
+
#
|
2
|
+
# advsearch.rb - advanced search servlet
|
3
|
+
#
|
4
|
+
# Copyright (C) 2004-2005 Satoru Takabayashi <satoru@namazu.org>
|
5
|
+
# All rights reserved.
|
6
|
+
# This is free software with ABSOLUTELY NO WARRANTY.
|
7
|
+
#
|
8
|
+
# You can redistribute it and/or modify it under the terms of
|
9
|
+
# the GNU General Public License version 2.
|
10
|
+
#
|
11
|
+
|
12
|
+
module Gonzui
|
13
|
+
class AdvancedSearchServlet < GonzuiAbstractServlet
|
14
|
+
def self.mount_point
|
15
|
+
"advsearch"
|
16
|
+
end
|
17
|
+
|
18
|
+
def do_make_status_line
|
19
|
+
[]
|
20
|
+
end
|
21
|
+
|
22
|
+
def make_target_select
|
23
|
+
tt = get_short_name(:target_type)
|
24
|
+
select = [:select, {:name => tt}]
|
25
|
+
oall = [:option, {:type => "radio", :name => tt,
|
26
|
+
:value => ""}, _("All")]
|
27
|
+
select.push(oall)
|
28
|
+
LangScan::Type.each_group {|group|
|
29
|
+
og = [:optgroup, {:label => _(group.name)}]
|
30
|
+
added_p = false
|
31
|
+
group.each {|type_info|
|
32
|
+
if @dbm.has_type?(type_info.type)
|
33
|
+
o = [:option, {:type => "radio", :name => tt,
|
34
|
+
:value => type_info.type}, _(type_info.name)]
|
35
|
+
og.push(o)
|
36
|
+
added_p = true
|
37
|
+
end
|
38
|
+
}
|
39
|
+
select.push(og) if added_p
|
40
|
+
}
|
41
|
+
return select
|
42
|
+
end
|
43
|
+
|
44
|
+
def make_nresults_select
|
45
|
+
nr = get_short_name(:nresults_per_page)
|
46
|
+
select = [:select, {:name => nr}]
|
47
|
+
@config.nresults_candidates.each {|n|
|
48
|
+
o = [:option, {:type => "radio", :name => nr,
|
49
|
+
:value => n}, sprintf(_("%d results"), n)]
|
50
|
+
select.push(o)
|
51
|
+
}
|
52
|
+
return select
|
53
|
+
end
|
54
|
+
|
55
|
+
def make_target_specific_search_form
|
56
|
+
form = [:form, { :method => "get",
|
57
|
+
:action => make_uri_general(SearchServlet)}]
|
58
|
+
|
59
|
+
ikeyword = [:input, {:type => "text", :size => 30,
|
60
|
+
:name => get_short_name(:basic_query),
|
61
|
+
:value => @search_query.keywords.join(" ")}]
|
62
|
+
iphrase = [:input, {:type => "text", :size => 30,
|
63
|
+
:name => get_short_name(:phrase_query),
|
64
|
+
:value => (@search_query.phrases.first or []).join(" ")}]
|
65
|
+
|
66
|
+
nresults_select = make_nresults_select
|
67
|
+
|
68
|
+
isubmit = [:input, {:type => "submit", :value => _("Search")}]
|
69
|
+
|
70
|
+
table = [:table]
|
71
|
+
table.push([:tr, [:td, {:width => "20%"}, _("Keyword")],
|
72
|
+
[:td, {:width => "30%"}, ikeyword],
|
73
|
+
[:td, {:width => "15%"}, nresults_select],
|
74
|
+
[:td, {:width => "15%"}, isubmit]])
|
75
|
+
table.push([:tr, [:td, {:width => "20%"}, _("Phrase")],
|
76
|
+
[:td, {:width => "30%"}, iphrase]])
|
77
|
+
|
78
|
+
table.push([:tr])
|
79
|
+
|
80
|
+
target_select = make_target_select
|
81
|
+
table.push([:tr, [:td, _("Target")],
|
82
|
+
[:td, target_select], [:td]])
|
83
|
+
|
84
|
+
format_select = make_format_select
|
85
|
+
table.push([:tr, [:td, _("Format")], [:td, format_select], [:td]])
|
86
|
+
|
87
|
+
license_select = make_license_select
|
88
|
+
table.push([:tr, [:td, _("License")], [:td, license_select], [:td]])
|
89
|
+
|
90
|
+
form.push(table)
|
91
|
+
return form
|
92
|
+
end
|
93
|
+
|
94
|
+
def make_advanced_search_form
|
95
|
+
form = make_target_specific_search_form
|
96
|
+
return [:div, {:class =>"advanced-search"}, form]
|
97
|
+
end
|
98
|
+
|
99
|
+
def do_GET(request, response)
|
100
|
+
init_servlet(request, response)
|
101
|
+
log()
|
102
|
+
|
103
|
+
html = make_html
|
104
|
+
title = make_title(_("Advanced Search"))
|
105
|
+
head = [:head, title, *make_meta_and_css]
|
106
|
+
body = [:body]
|
107
|
+
|
108
|
+
h1 = make_h1
|
109
|
+
status_line = make_status_line(_("Advanced Search"))
|
110
|
+
content = make_advanced_search_form
|
111
|
+
footer = make_footer
|
112
|
+
body.push(h1, status_line, content, footer)
|
113
|
+
|
114
|
+
html.push(head)
|
115
|
+
html.push(body)
|
116
|
+
set_content_type_text_html
|
117
|
+
response.body = format_html(html)
|
118
|
+
end
|
119
|
+
|
120
|
+
GonzuiServlet.register(self)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
@@ -0,0 +1,24 @@
|
|
1
|
+
#
|
2
|
+
# filehandler.rb - file handler servlet
|
3
|
+
#
|
4
|
+
# Copyright (C) 2004-2005 Satoru Takabayashi <satoru@namazu.org>
|
5
|
+
# All rights reserved.
|
6
|
+
# This is free software with ABSOLUTELY NO WARRANTY.
|
7
|
+
#
|
8
|
+
# You can redistribute it and/or modify it under the terms of
|
9
|
+
# the GNU General Public License version 2.
|
10
|
+
#
|
11
|
+
|
12
|
+
module Gonzui
|
13
|
+
class FileHandler < WEBrick::HTTPServlet::FileHandler
|
14
|
+
def self.mount_point
|
15
|
+
"doc"
|
16
|
+
end
|
17
|
+
|
18
|
+
def initialize(server, config, logger, dbm, catalogs)
|
19
|
+
super(server, config.doc_directory)
|
20
|
+
end
|
21
|
+
|
22
|
+
GonzuiServlet.register(self)
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
#
|
2
|
+
# jsfeed - javascript-feed servlet
|
3
|
+
#
|
4
|
+
# Copyright (C) 2004-2005 Satoru Takabayashi <satoru@namazu.org>
|
5
|
+
# All rights reserved.
|
6
|
+
# This is free software with ABSOLUTELY NO WARRANTY.
|
7
|
+
#
|
8
|
+
# You can redistribute it and/or modify it under the terms of
|
9
|
+
# the GNU General Public License version 2.
|
10
|
+
#
|
11
|
+
|
12
|
+
module Gonzui
|
13
|
+
class JSFeedServlet < GonzuiAbstractServlet
|
14
|
+
def self.mount_point
|
15
|
+
"jsfeed"
|
16
|
+
end
|
17
|
+
|
18
|
+
def do_GET(request, response)
|
19
|
+
init_servlet(request, response)
|
20
|
+
path = make_path
|
21
|
+
log(path)
|
22
|
+
|
23
|
+
from = to = nil
|
24
|
+
if m = /^(\d+)-(\d+)$/.match(request.query_string)
|
25
|
+
from = m[1].to_i
|
26
|
+
to = m[2].to_i
|
27
|
+
end
|
28
|
+
|
29
|
+
if from and to
|
30
|
+
path_id = @dbm.get_path_id(path)
|
31
|
+
if path_id
|
32
|
+
content = @dbm.get_content(path_id)
|
33
|
+
lineno = 0
|
34
|
+
lines = []
|
35
|
+
range = Range.new(from, to)
|
36
|
+
content.each_line {|line|
|
37
|
+
lineno += 1
|
38
|
+
if range.include?(lineno)
|
39
|
+
line_with_lineno = sprintf("%5d: %s", lineno, line)
|
40
|
+
line_with_lineno.chop!
|
41
|
+
lines.push(HTMLUtils.escape(line_with_lineno))
|
42
|
+
end
|
43
|
+
}
|
44
|
+
snippet = lines.join("<br />")
|
45
|
+
response.body = sprintf("document.writeln('<pre>%s</pre>');",
|
46
|
+
snippet)
|
47
|
+
response['Content-Type'] = "application/x-javascript"
|
48
|
+
else
|
49
|
+
response.body = sprintf("%s: not found", path)
|
50
|
+
response.status = 404
|
51
|
+
response['Content-Type'] = "text/html"
|
52
|
+
end
|
53
|
+
else
|
54
|
+
response.body = "invalid query"
|
55
|
+
response['Content-Type'] = "text/html"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
GonzuiServlet.register(self)
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,445 @@
|
|
1
|
+
#
|
2
|
+
# markup.rb - markup servlet
|
3
|
+
#
|
4
|
+
# Copyright (C) 2004-2005 Satoru Takabayashi <satoru@namazu.org>
|
5
|
+
# All rights reserved.
|
6
|
+
# This is free software with ABSOLUTELY NO WARRANTY.
|
7
|
+
#
|
8
|
+
# You can redistribute it and/or modify it under the terms of
|
9
|
+
# the GNU General Public License version 2.
|
10
|
+
#
|
11
|
+
|
12
|
+
require 'stringio'
|
13
|
+
require 'zlib'
|
14
|
+
require 'strscan'
|
15
|
+
|
16
|
+
module Gonzui
|
17
|
+
class TextBeautifier
|
18
|
+
def initialize(content, digest, occurrences, search_uri)
|
19
|
+
@content = content
|
20
|
+
@digest = digest # to be destroyed
|
21
|
+
@occurrences = occurrences # to be destroyed
|
22
|
+
@search_uri = search_uri
|
23
|
+
|
24
|
+
@break_points = [0, @content.length]
|
25
|
+
@lines = {}
|
26
|
+
pos = lineno = 0
|
27
|
+
@content.each_line {|line|
|
28
|
+
lineno += 1
|
29
|
+
@break_points.push(pos)
|
30
|
+
@lines[pos] = [lineno, line]
|
31
|
+
pos += line.length
|
32
|
+
}
|
33
|
+
@digest.each {|info|
|
34
|
+
@break_points.push(info.byteno)
|
35
|
+
@break_points.push(info.end_byteno)
|
36
|
+
}
|
37
|
+
@occurrences.each {|occ|
|
38
|
+
@break_points.push(occ.byteno)
|
39
|
+
@break_points.push(occ.end_byteno)
|
40
|
+
}
|
41
|
+
@break_points.uniq!
|
42
|
+
@break_points.sort!
|
43
|
+
|
44
|
+
@info = @digest.shift
|
45
|
+
@occ = @occurrences.shift
|
46
|
+
@seen_ids = {}
|
47
|
+
@latest_id = "0"
|
48
|
+
end
|
49
|
+
|
50
|
+
def make_line_mark(lineno)
|
51
|
+
anchor = "l" + lineno.to_s
|
52
|
+
[:span, {:class => "lineno", :onclick => "olnc(this);"},
|
53
|
+
[:a, {:id => anchor, :name => anchor, :href => "#" + anchor},
|
54
|
+
sprintf("%5d: ", lineno)]]
|
55
|
+
end
|
56
|
+
|
57
|
+
def choose_target_type
|
58
|
+
case @info.type
|
59
|
+
when :fundef
|
60
|
+
:funcall
|
61
|
+
when :funcall
|
62
|
+
:fundef
|
63
|
+
when :fundecl
|
64
|
+
:fundef
|
65
|
+
else
|
66
|
+
assert_not_reached
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def decorate(text)
|
71
|
+
unless @seen_ids.include?(text)
|
72
|
+
@seen_ids[text] = @latest_id
|
73
|
+
@latest_id = @latest_id.next
|
74
|
+
end
|
75
|
+
id = @seen_ids[text]
|
76
|
+
inner = [:span, {:class => id, :onmouseover => "hl('#{id}');"}, text]
|
77
|
+
part = [:span, {:class => @info.type.to_s}, inner]
|
78
|
+
|
79
|
+
if LangScan::Type.function?(@info.type)
|
80
|
+
tt = choose_target_type
|
81
|
+
query_string = sprintf("%s:%s", tt, HTTPUtils.escape_form(text))
|
82
|
+
uri = @search_uri + query_string
|
83
|
+
part = [:a, {:href => uri}, part]
|
84
|
+
end
|
85
|
+
return part
|
86
|
+
end
|
87
|
+
|
88
|
+
def markup_part(bp, ep)
|
89
|
+
part = @content[bp...ep]
|
90
|
+
if @info and (bp == @info.byteno or @info.range.include?(bp))
|
91
|
+
part = decorate(part)
|
92
|
+
@info = @digest.shift if @info.end_byteno <= ep
|
93
|
+
end
|
94
|
+
if @occ and (bp == @occ.byteno or @occ.range.include?(bp))
|
95
|
+
part = [:strong, {:class => "highlight"}, part]
|
96
|
+
@occ = @occurrences.shift if @occ.end_byteno <= ep
|
97
|
+
end
|
98
|
+
return part
|
99
|
+
end
|
100
|
+
|
101
|
+
def make_lineno_part(bp)
|
102
|
+
lineno, line = @lines[bp]
|
103
|
+
[:span, {:class => "line", :title => line}, make_line_mark(lineno)]
|
104
|
+
end
|
105
|
+
|
106
|
+
def beautify
|
107
|
+
code = []
|
108
|
+
bp = @break_points.shift
|
109
|
+
line = nil
|
110
|
+
while not @break_points.empty?
|
111
|
+
ep = @break_points.shift
|
112
|
+
if @lines.include?(bp)
|
113
|
+
code.push(line) if line
|
114
|
+
line = make_lineno_part(bp)
|
115
|
+
end
|
116
|
+
part = markup_part(bp, ep)
|
117
|
+
line.push(part)
|
118
|
+
bp = ep
|
119
|
+
end
|
120
|
+
code.push(line) if line
|
121
|
+
return code
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
class MarkupServlet < GonzuiAbstractServlet
|
126
|
+
def self.mount_point
|
127
|
+
"markup"
|
128
|
+
end
|
129
|
+
|
130
|
+
def make_breadcrumbs(path)
|
131
|
+
parts = path.split("/")
|
132
|
+
breadcrumbs = (1 .. parts.length).map {|i|
|
133
|
+
[ parts[i - 1], parts[0, i]]
|
134
|
+
}.map {|part, parts|
|
135
|
+
path = parts.join("/")
|
136
|
+
uri = make_markup_uri(parts.join("/"), @search_query)
|
137
|
+
[:a, {:href => uri}, part]
|
138
|
+
}
|
139
|
+
(breadcrumbs.length - 1).times {|i|
|
140
|
+
breadcrumbs.insert(i * 2 + 1, "/")
|
141
|
+
}
|
142
|
+
return [:span, *breadcrumbs]
|
143
|
+
end
|
144
|
+
|
145
|
+
def do_make_status_line(method)
|
146
|
+
items = []
|
147
|
+
|
148
|
+
case method
|
149
|
+
when :markup_file
|
150
|
+
if @path_id
|
151
|
+
bare = [:a, {:href => make_source_uri(@path)},
|
152
|
+
_("bare source")]
|
153
|
+
permlink = [:a, {:href => make_markup_uri(@path)},
|
154
|
+
_("permlink")]
|
155
|
+
items.push(bare)
|
156
|
+
items.push(permlink)
|
157
|
+
end
|
158
|
+
when :list_files
|
159
|
+
if @total
|
160
|
+
items.push([:span, [:strong, @total], _(" contents.")])
|
161
|
+
end
|
162
|
+
when :list_packages
|
163
|
+
if @to and @total
|
164
|
+
packages = [:span, _("Packages "),
|
165
|
+
[:strong, commify(@from + 1)], " - ",
|
166
|
+
[:strong, commify(@to)], _(" of "),
|
167
|
+
[:strong, commify(@total)], _(".")]
|
168
|
+
items.push(packages)
|
169
|
+
end
|
170
|
+
end
|
171
|
+
return items
|
172
|
+
end
|
173
|
+
|
174
|
+
def calc_ncolumns(items)
|
175
|
+
sum = items.inject(0) {|a, b|
|
176
|
+
name = b.first
|
177
|
+
a + name.length
|
178
|
+
}
|
179
|
+
average = sum / items.length
|
180
|
+
ncolumns = [40 / average, items.length].min
|
181
|
+
ncolumns = 1 if ncolumns == 0
|
182
|
+
return ncolumns
|
183
|
+
end
|
184
|
+
|
185
|
+
def make_table(items)
|
186
|
+
table = [:table, {:class => "fullwidth"}]
|
187
|
+
return table if items.empty?
|
188
|
+
ncolumns = calc_ncolumns(items)
|
189
|
+
width = sprintf("%d%%", 100/ncolumns)
|
190
|
+
|
191
|
+
nrows = (items.length - 1) / ncolumns + 1
|
192
|
+
nrows.times {|i|
|
193
|
+
k = if (i + 1) % 2 == 0 then "even" else "odd" end
|
194
|
+
row = [:tr, {:class => k}]
|
195
|
+
ncolumns.times {|j|
|
196
|
+
# item = items[j * nrows + i] # for vertical arrange
|
197
|
+
item = items[i * ncolumns + j]
|
198
|
+
value = if item
|
199
|
+
name, klass, image, uri, title = item
|
200
|
+
tr = [:tr]
|
201
|
+
if image
|
202
|
+
img = [:img, {:src => image, :alt => ""}]
|
203
|
+
tr << [:td, [:a, {:href => uri}, img]]
|
204
|
+
end
|
205
|
+
a = [:a, {:class => klass, :href =>uri,:title =>title}, name]
|
206
|
+
tr << [:td, a]
|
207
|
+
[:table, {:class => "item"}, tr]
|
208
|
+
else
|
209
|
+
make_spacer
|
210
|
+
end
|
211
|
+
k = if j == 0 then "first" else "nonfirst" end
|
212
|
+
td = [:td, {:width => width, :class => k}, value]
|
213
|
+
row.push(td)
|
214
|
+
}
|
215
|
+
table.push(row)
|
216
|
+
}
|
217
|
+
return table
|
218
|
+
end
|
219
|
+
|
220
|
+
def make_title_for_path(path, file_p)
|
221
|
+
title = if file_p
|
222
|
+
path_id = @dbm.get_path_id(path)
|
223
|
+
info = @dbm.get_content_info(path_id)
|
224
|
+
sprintf(_("Size: %s (%s lines)"),
|
225
|
+
format_bytes(info.size),
|
226
|
+
commify(info.nlines))
|
227
|
+
else
|
228
|
+
""
|
229
|
+
end
|
230
|
+
return title
|
231
|
+
end
|
232
|
+
|
233
|
+
def make_table_of_files(paths)
|
234
|
+
items = paths.map {|path, file_p|
|
235
|
+
basename = File.basename(path)
|
236
|
+
klass = if file_p then "file" else "directory" end
|
237
|
+
image = if file_p
|
238
|
+
make_doc_uri("text.png")
|
239
|
+
else
|
240
|
+
make_doc_uri("folder.png")
|
241
|
+
end
|
242
|
+
uri = make_markup_uri(path, @search_query)
|
243
|
+
title = make_title_for_path(path, file_p)
|
244
|
+
[basename, klass, image, uri, title]
|
245
|
+
}
|
246
|
+
return make_table(items)
|
247
|
+
end
|
248
|
+
|
249
|
+
def make_table_of_packages(package_names)
|
250
|
+
items = package_names.map {|package_name|
|
251
|
+
package_id = @dbm.get_package_id(package_name)
|
252
|
+
uri = make_markup_uri(package_name)
|
253
|
+
title = ""
|
254
|
+
[package_name, "directory", nil, uri, title]
|
255
|
+
}
|
256
|
+
return make_table(items)
|
257
|
+
end
|
258
|
+
|
259
|
+
def list_files
|
260
|
+
path_parts = @path.split("/")
|
261
|
+
depth = path_parts.length
|
262
|
+
|
263
|
+
package_id = @dbm.get_package_id(@package_name)
|
264
|
+
path_ids = @dbm.get_path_ids(package_id)
|
265
|
+
paths = path_ids.map {|path_id|
|
266
|
+
@dbm.get_path(path_id)
|
267
|
+
}.map {|path|
|
268
|
+
path.split("/")
|
269
|
+
}.find_all {|parts|
|
270
|
+
parts.length > depth and parts[0, depth] == path_parts
|
271
|
+
}.map {|parts|
|
272
|
+
file_p = parts.length == depth + 1
|
273
|
+
[parts[0, depth + 1].join("/"), file_p]
|
274
|
+
}.uniq
|
275
|
+
if paths.empty?
|
276
|
+
return ""
|
277
|
+
else
|
278
|
+
@total = paths.length
|
279
|
+
return make_table_of_files(paths)
|
280
|
+
end
|
281
|
+
end
|
282
|
+
|
283
|
+
def do_make_navi(from)
|
284
|
+
make_markup_uri("", nil, :from => from)
|
285
|
+
end
|
286
|
+
|
287
|
+
def list_packages
|
288
|
+
# FIXME: sorting every time is not efficient.
|
289
|
+
all = []
|
290
|
+
@dbm.each_package_name {|package_name|
|
291
|
+
all.push(package_name)
|
292
|
+
}
|
293
|
+
all.sort!
|
294
|
+
|
295
|
+
package_names = all[@from, @config.max_packages_per_page]
|
296
|
+
if package_names
|
297
|
+
@to = @from + package_names.length
|
298
|
+
@total = all.length
|
299
|
+
table = make_table_of_packages(package_names)
|
300
|
+
navi = make_navi(all.length, @from, @config.max_packages_per_page)
|
301
|
+
return [:div, table, navi]
|
302
|
+
else
|
303
|
+
return ""
|
304
|
+
end
|
305
|
+
end
|
306
|
+
|
307
|
+
def markup_source
|
308
|
+
content = @dbm.get_content(@path_id)
|
309
|
+
digest = @dbm.get_digest(@path_id)
|
310
|
+
occurrences = if @search_query.string.empty?
|
311
|
+
[]
|
312
|
+
else
|
313
|
+
search_query = @search_query.clone
|
314
|
+
search_query.path ||= @path
|
315
|
+
searcher = Searcher.new(@dbm, search_query,
|
316
|
+
@config.max_results_overall)
|
317
|
+
result = searcher.search
|
318
|
+
item = result.first
|
319
|
+
if item and not item.list.empty?
|
320
|
+
item.list
|
321
|
+
else
|
322
|
+
[]
|
323
|
+
end
|
324
|
+
end
|
325
|
+
search_uri = make_search_uri_partial("")
|
326
|
+
beautifier = TextBeautifier.new(content, digest, occurrences, search_uri)
|
327
|
+
return beautifier.beautify
|
328
|
+
end
|
329
|
+
|
330
|
+
def make_isearch_form
|
331
|
+
isearch = [:div, {:class => "isearch"}]
|
332
|
+
form = [:form, {:method => "get", :action => "",
|
333
|
+
:onsubmit => "return false;"}]
|
334
|
+
p = [:p]
|
335
|
+
p.push(_("Search this content: "))
|
336
|
+
p.push([:input, {:type => "text", :name => "g", :size => "20",
|
337
|
+
:onkeyup => "isearch(this.value);",
|
338
|
+
:value => ""
|
339
|
+
}])
|
340
|
+
p.push(" ")
|
341
|
+
form.push(p)
|
342
|
+
isearch.push(form)
|
343
|
+
return isearch
|
344
|
+
end
|
345
|
+
|
346
|
+
def markup_file
|
347
|
+
path = @dbm.get_path(@path_id)
|
348
|
+
|
349
|
+
mime_type = get_mime_type(path)
|
350
|
+
media_type = get_media_type(path)
|
351
|
+
if media_type == "image"
|
352
|
+
img = [:img, {:src => make_source_uri(path),
|
353
|
+
:alt => path }]
|
354
|
+
content = [:div, {:class => "image"}, img]
|
355
|
+
elsif mime_type == "text/html"
|
356
|
+
iframe = [:iframe, {:src => make_source_uri(path),
|
357
|
+
:width => "100%", :height => "400"},
|
358
|
+
[:a, {:href => make_source_uri(path)}, path]
|
359
|
+
]
|
360
|
+
content = iframe
|
361
|
+
else
|
362
|
+
content = [:div]
|
363
|
+
isearch = make_isearch_form
|
364
|
+
content.push(isearch)
|
365
|
+
code = markup_source
|
366
|
+
content.push([:pre, *code])
|
367
|
+
end
|
368
|
+
return content
|
369
|
+
end
|
370
|
+
|
371
|
+
def make_not_found
|
372
|
+
sprintf(_("No contents were found matching %s"),
|
373
|
+
@path)
|
374
|
+
end
|
375
|
+
|
376
|
+
def gzip(string)
|
377
|
+
strio = StringIO.new
|
378
|
+
writer = Zlib::GzipWriter.new(strio)
|
379
|
+
writer.print(string)
|
380
|
+
writer.finish
|
381
|
+
return strio.string
|
382
|
+
end
|
383
|
+
|
384
|
+
def set_response(html)
|
385
|
+
set_content_type_text_html
|
386
|
+
body = format_html(html)
|
387
|
+
if @request.gzip_encoding_supported?
|
388
|
+
@response["Content-Encoding"] = "gzip"
|
389
|
+
@response.body = gzip(body)
|
390
|
+
else
|
391
|
+
@response.body = body
|
392
|
+
end
|
393
|
+
end
|
394
|
+
|
395
|
+
def choose_method
|
396
|
+
method = :make_not_found
|
397
|
+
if @path.empty?
|
398
|
+
method = :list_packages
|
399
|
+
title = make_title(_("List of Packages"))
|
400
|
+
status_title = _("List of Packages")
|
401
|
+
else
|
402
|
+
@path_id = @dbm.get_path_id(@path)
|
403
|
+
@package_name = @path.split("/").first
|
404
|
+
if @path_id
|
405
|
+
method = :markup_file
|
406
|
+
elsif @dbm.has_package?(@package_name)
|
407
|
+
method = :list_files
|
408
|
+
end
|
409
|
+
title = make_title(@path)
|
410
|
+
status_title = make_breadcrumbs(@path)
|
411
|
+
end
|
412
|
+
return method, title, status_title
|
413
|
+
end
|
414
|
+
|
415
|
+
def do_GET(request, response)
|
416
|
+
init_servlet(request, response)
|
417
|
+
log(@path)
|
418
|
+
|
419
|
+
@path = make_path
|
420
|
+
@to = nil
|
421
|
+
@total = nil
|
422
|
+
|
423
|
+
method, title, status_title = choose_method
|
424
|
+
|
425
|
+
html = make_html
|
426
|
+
head = [:head, title, make_script, *make_meta_and_css]
|
427
|
+
body = [:body, {:onload => "initCache();",
|
428
|
+
:onclick => "clearHighlight();" }]
|
429
|
+
body.push(make_h1)
|
430
|
+
body.push(make_search_form)
|
431
|
+
content = self.send(method)
|
432
|
+
|
433
|
+
status_line = make_status_line(status_title, method)
|
434
|
+
body.push(status_line)
|
435
|
+
body.push(content)
|
436
|
+
body.push(make_footer)
|
437
|
+
|
438
|
+
html.push(head)
|
439
|
+
html.push(body)
|
440
|
+
set_response(html)
|
441
|
+
end
|
442
|
+
|
443
|
+
GonzuiServlet.register(self)
|
444
|
+
end
|
445
|
+
end
|