gonzui 1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (116) hide show
  1. data/AUTHORS.txt +9 -0
  2. data/History.txt +5539 -0
  3. data/Manifest.txt +115 -0
  4. data/PostInstall.txt +17 -0
  5. data/README.rdoc +149 -0
  6. data/Rakefile +28 -0
  7. data/bin/gonzui-db +167 -0
  8. data/bin/gonzui-import +177 -0
  9. data/bin/gonzui-remove +58 -0
  10. data/bin/gonzui-search +68 -0
  11. data/bin/gonzui-server +176 -0
  12. data/bin/gonzui-update +53 -0
  13. data/data/gonzui/catalog/catalog.ja +80 -0
  14. data/data/gonzui/doc/favicon.ico +0 -0
  15. data/data/gonzui/doc/folder.png +0 -0
  16. data/data/gonzui/doc/gonzui.css +279 -0
  17. data/data/gonzui/doc/gonzui.js +111 -0
  18. data/data/gonzui/doc/text.png +0 -0
  19. data/data/gonzuirc.sample +29 -0
  20. data/ext/autopack/autopack.c +88 -0
  21. data/ext/autopack/extconf.rb +3 -0
  22. data/ext/delta/delta.c +147 -0
  23. data/ext/delta/extconf.rb +5 -0
  24. data/ext/texttokenizer/extconf.rb +5 -0
  25. data/ext/texttokenizer/texttokenizer.c +93 -0
  26. data/ext/xmlformatter/extconf.rb +5 -0
  27. data/ext/xmlformatter/xmlformatter.c +207 -0
  28. data/lib/gonzui.rb +59 -0
  29. data/lib/gonzui/apt.rb +193 -0
  30. data/lib/gonzui/bdbdbm.rb +118 -0
  31. data/lib/gonzui/cmdapp.rb +14 -0
  32. data/lib/gonzui/cmdapp/app.rb +175 -0
  33. data/lib/gonzui/cmdapp/search.rb +134 -0
  34. data/lib/gonzui/config.rb +117 -0
  35. data/lib/gonzui/content.rb +19 -0
  36. data/lib/gonzui/dbm.rb +673 -0
  37. data/lib/gonzui/deindexer.rb +162 -0
  38. data/lib/gonzui/delta.rb +49 -0
  39. data/lib/gonzui/extractor.rb +347 -0
  40. data/lib/gonzui/fetcher.rb +309 -0
  41. data/lib/gonzui/gettext.rb +144 -0
  42. data/lib/gonzui/importer.rb +84 -0
  43. data/lib/gonzui/indexer.rb +316 -0
  44. data/lib/gonzui/info.rb +80 -0
  45. data/lib/gonzui/license.rb +100 -0
  46. data/lib/gonzui/logger.rb +48 -0
  47. data/lib/gonzui/monitor.rb +177 -0
  48. data/lib/gonzui/progressbar.rb +235 -0
  49. data/lib/gonzui/remover.rb +38 -0
  50. data/lib/gonzui/searcher.rb +330 -0
  51. data/lib/gonzui/searchquery.rb +235 -0
  52. data/lib/gonzui/searchresult.rb +111 -0
  53. data/lib/gonzui/updater.rb +254 -0
  54. data/lib/gonzui/util.rb +415 -0
  55. data/lib/gonzui/vcs.rb +128 -0
  56. data/lib/gonzui/webapp.rb +25 -0
  57. data/lib/gonzui/webapp/advsearch.rb +123 -0
  58. data/lib/gonzui/webapp/filehandler.rb +24 -0
  59. data/lib/gonzui/webapp/jsfeed.rb +61 -0
  60. data/lib/gonzui/webapp/markup.rb +445 -0
  61. data/lib/gonzui/webapp/search.rb +269 -0
  62. data/lib/gonzui/webapp/servlet.rb +319 -0
  63. data/lib/gonzui/webapp/snippet.rb +155 -0
  64. data/lib/gonzui/webapp/source.rb +37 -0
  65. data/lib/gonzui/webapp/stat.rb +137 -0
  66. data/lib/gonzui/webapp/top.rb +63 -0
  67. data/lib/gonzui/webapp/uri.rb +140 -0
  68. data/lib/gonzui/webapp/webrick.rb +48 -0
  69. data/script/console +10 -0
  70. data/script/destroy +14 -0
  71. data/script/generate +14 -0
  72. data/script/makemanifest.rb +21 -0
  73. data/tasks/extconf.rake +13 -0
  74. data/tasks/extconf/autopack.rake +43 -0
  75. data/tasks/extconf/delta.rake +43 -0
  76. data/tasks/extconf/texttokenizer.rake +43 -0
  77. data/tasks/extconf/xmlformatter.rake +43 -0
  78. data/test/_external_tools.rb +13 -0
  79. data/test/_test-util.rb +142 -0
  80. data/test/foo/Makefile.foo +66 -0
  81. data/test/foo/bar.c +5 -0
  82. data/test/foo/bar.h +6 -0
  83. data/test/foo/foo.c +25 -0
  84. data/test/foo/foo.spec +33 -0
  85. data/test/test_apt.rb +42 -0
  86. data/test/test_autopack_extn.rb +7 -0
  87. data/test/test_bdbdbm.rb +79 -0
  88. data/test/test_cmdapp-app.rb +35 -0
  89. data/test/test_cmdapp-search.rb +99 -0
  90. data/test/test_config.rb +28 -0
  91. data/test/test_content.rb +15 -0
  92. data/test/test_dbm.rb +171 -0
  93. data/test/test_deindexer.rb +50 -0
  94. data/test/test_delta.rb +66 -0
  95. data/test/test_extractor.rb +78 -0
  96. data/test/test_fetcher.rb +75 -0
  97. data/test/test_gettext.rb +50 -0
  98. data/test/test_gonzui.rb +11 -0
  99. data/test/test_helper.rb +10 -0
  100. data/test/test_importer.rb +56 -0
  101. data/test/test_indexer.rb +37 -0
  102. data/test/test_info.rb +82 -0
  103. data/test/test_license.rb +49 -0
  104. data/test/test_logger.rb +60 -0
  105. data/test/test_monitor.rb +23 -0
  106. data/test/test_searcher.rb +37 -0
  107. data/test/test_searchquery.rb +27 -0
  108. data/test/test_searchresult.rb +43 -0
  109. data/test/test_texttokenizer.rb +47 -0
  110. data/test/test_updater.rb +95 -0
  111. data/test/test_util.rb +149 -0
  112. data/test/test_vcs.rb +61 -0
  113. data/test/test_webapp-markup.rb +42 -0
  114. data/test/test_webapp-util.rb +19 -0
  115. data/test/test_webapp-xmlformatter.rb +19 -0
  116. metadata +291 -0
@@ -0,0 +1,155 @@
1
+ #
2
+ # snippet.rb - snippet implementation
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 SnippetMaker
14
+ include URIMaker
15
+
16
+ def initialize(content, result_item, link_uri = nil)
17
+ @content = content
18
+ @result_item = result_item
19
+ @link_uri = link_uri
20
+
21
+ # FIXME: should be customizable?
22
+ @ncontexts = 1
23
+ end
24
+
25
+ private
26
+ def make_emphasized_line(lineno, line_range, *occ_list)
27
+ line = [:span]
28
+ occ_list.each {|occ|
29
+ occ_range = (occ.byteno ... (occ.byteno + occ.length))
30
+ pre = range = nil
31
+ if line_range.include?(occ.byteno)
32
+ pre = @content.substring(line_range.first...occ.byteno)
33
+ range = (occ.byteno ... [occ_range.last, line_range.last].min)
34
+ elsif occ_range.include?(line_range.first)
35
+ range = (line_range.first ... [occ_range.last, line_range.last].min)
36
+ end
37
+ line.push(pre) if pre
38
+ if range
39
+ text = @content[range]
40
+ line.push([:strong, text])
41
+ line_range = (range.last ... line_range.last)
42
+ end
43
+ }
44
+ remaining = @content.substring(line_range)
45
+ line.push(remaining)
46
+ return line
47
+ end
48
+
49
+ def make_occurrences_by_lineno
50
+ occurrences_by_lineno = {}
51
+ @result_item.list.sort_by {|occ| occ.byteno}.each {|occ|
52
+ occurrences_by_lineno[occ.lineno] ||= []
53
+ occurrences_by_lineno[occ.lineno].push(occ)
54
+ }
55
+ return occurrences_by_lineno
56
+ end
57
+
58
+ def add_contexts(lines_with_lineno, occ)
59
+ @content.each_line_range(occ.byteno, @ncontexts) {|lineno_offset, range|
60
+ lineno = occ.lineno + lineno_offset
61
+ line = @content.substring(range)
62
+ lines_with_lineno.push([line, lineno]) unless lineno == occ.lineno
63
+ }
64
+ return lines_with_lineno.sort_by {|line, lineno| lineno }
65
+ end
66
+
67
+ def make_kwic_single
68
+ lines_with_lineno = []
69
+ occ = @result_item.list.first
70
+ text = @content[occ.byteno, occ.length]
71
+ @content.each_line_range(occ.byteno, @ncontexts) {|lineno_offset, range|
72
+ lineno = occ.lineno + lineno_offset
73
+ line = make_emphasized_line(lineno, range, occ)
74
+ lines_with_lineno.push([line, lineno])
75
+ }
76
+ return lines_with_lineno
77
+ end
78
+
79
+ def make_kwic_multi
80
+ seen = {}
81
+ lines_with_lineno = []
82
+ occurrences_by_lineno = make_occurrences_by_lineno
83
+ occurrences_by_lineno.keys.sort.each {|lineno|
84
+ occ_list = occurrences_by_lineno[lineno]
85
+ range = @content.line_range(occ_list.first.byteno)
86
+ line = make_emphasized_line(lineno, range, *occ_list)
87
+ lines_with_lineno.push([line, lineno])
88
+ }
89
+ if occurrences_by_lineno.length == 1
90
+ occ = @result_item.list.first
91
+ lines_with_lineno = add_contexts(lines_with_lineno, occ)
92
+ end
93
+ return lines_with_lineno
94
+ end
95
+
96
+ def make_kwic
97
+ if @result_item.list.length == 1
98
+ return make_kwic_single
99
+ else
100
+ return make_kwic_multi
101
+ end
102
+ end
103
+
104
+ def collect_context_lines
105
+ context_lines = {}
106
+
107
+ occurrences_by_lineno = make_occurrences_by_lineno
108
+ occurrences_by_lineno.keys.sort.each {|lineno|
109
+ occ_list = occurrences_by_lineno[lineno]
110
+ range = @content.line_range(occ_list.first.byteno)
111
+ occ = occ_list.first
112
+ @content.each_line_range(occ.byteno, @ncontexts) {|lineno_offset,range|
113
+ lineno = occ.lineno + lineno_offset
114
+ next if context_lines.has_key?(lineno) and lineno_offset != 0
115
+ line = make_emphasized_line(lineno, range, *occ_list)
116
+ context_lines[lineno] = line
117
+ }
118
+ }
119
+ return context_lines
120
+ end
121
+
122
+ def make_separator
123
+ [:div, {:class => "separator"}, ""]
124
+ end
125
+
126
+ public
127
+ def make_line_oriented_kwic
128
+ lines_with_lineno = make_kwic
129
+ pre = [:pre, {:class => "lines"}]
130
+ lines_with_lineno.sort_by {|line, lineno|
131
+ lineno
132
+ }.each {|line, lineno|
133
+ lineno_uri = make_lineno_uri(@link_uri, lineno)
134
+ lineno_mark = [:a, {:href => lineno_uri}, lineno.to_s + ": "]
135
+ pre.push(lineno_mark, line)
136
+ pre.push("\n")
137
+ }
138
+ return pre
139
+ end
140
+
141
+ def make_context_grep
142
+ context_lines = collect_context_lines
143
+ pre = [:pre, {:class => "lines"}]
144
+ prev_lineno = nil
145
+ context_lines.keys.sort.each {|lineno|
146
+ lineno_uri = make_lineno_uri(@link_uri, lineno)
147
+ lineno_mark = [:a, {:href => lineno_uri }, lineno.to_s + ": "]
148
+ pre.push(make_separator)if prev_lineno and lineno > prev_lineno + 1
149
+ pre.push(lineno_mark, context_lines[lineno], "\n")
150
+ prev_lineno = lineno
151
+ }
152
+ return pre
153
+ end
154
+ end
155
+ end
@@ -0,0 +1,37 @@
1
+ #
2
+ # source.rb - source 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 SourceServlet < GonzuiAbstractServlet
14
+ def self.mount_point
15
+ "source"
16
+ end
17
+
18
+ def do_GET(request, response)
19
+ init_servlet(request, response)
20
+ path = make_path
21
+ log(path)
22
+
23
+ path_id = @dbm.get_path_id(path)
24
+ if path_id
25
+ content = @dbm.get_content(path_id)
26
+ response.body = content
27
+ mime_type = get_mime_type(path)
28
+ response["Content-Type"] = mime_type
29
+ else
30
+ response.body = sprintf("%s: not found", path)
31
+ response.status = 404
32
+ end
33
+ end
34
+
35
+ GonzuiServlet.register(self)
36
+ end
37
+ end
@@ -0,0 +1,137 @@
1
+ #
2
+ # stat.rb - statistics 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 StatisticsServlet < GonzuiAbstractServlet
14
+ def self.mount_point
15
+ "stat"
16
+ end
17
+
18
+ RankingMax = 100
19
+
20
+ def choose_tr_class(i)
21
+ if (i + 1) % 2 == 0 then "even" else "odd" end
22
+ end
23
+
24
+ def make_heading(*items)
25
+ tr = [:tr, {:class => "heading"}]
26
+ items.each {|string, klass, colspan|
27
+ td = [:td, {:class => klass}, string]
28
+ td[1][:colspan] = colspan if colspan
29
+ tr.push(td)
30
+ }
31
+ return tr
32
+ end
33
+
34
+ def make_bar(freq, max)
35
+ percentage = freq * 100 / max
36
+ style = "width: #{percentage}px;"
37
+ bar = [:div, {:class => "bar", :style => style}, ""]
38
+ end
39
+
40
+ def do_make_status_line
41
+ []
42
+ end
43
+
44
+ def make_tr(first, second, third = nil)
45
+ tr = [:tr]
46
+ td1 = [:td, {:class => "first", :width => "76%"}, first]
47
+ if third
48
+ td2 = [:td, {:class => "nonfirst-right", :width => "12%"},
49
+ commify(second)]
50
+ td3 = [:td, {:width => "12%"}, third]
51
+ else
52
+ td2 = [:td, {:class => "nonfirst-center", :width => "24%"},
53
+ commify(second)]
54
+ end
55
+ tr.push(td1)
56
+ tr.push(td2)
57
+ tr.push(td3) if td3
58
+ return tr
59
+ end
60
+
61
+ def make_format_table
62
+ table = [:table, {:class => "fullwidth"}]
63
+ heading = make_heading([_("Contents by Format"), "first", 3])
64
+ table.push(heading)
65
+ formats = []
66
+ max = -1
67
+ @dbm.each_format {|format_id, format_abbrev, format_name|
68
+ ncontents = @dbm.get_ncontents_by_format_id(format_id)
69
+ formats.push([format_id, format_abbrev, format_name, ncontents])
70
+ max = [max, ncontents].max
71
+ }
72
+ return if formats.empty?
73
+ formats = formats.sort_by {|id, abbr, name, ncontents| - ncontents}
74
+ formats.each_with_index {|item, i|
75
+ id, abbr, name, ncontents = item
76
+ text = name
77
+ tr = make_tr(text, ncontents, make_bar(ncontents, max))
78
+ k = choose_tr_class(i)
79
+ tr.insert(1, {:class => k})
80
+ table.push(tr)
81
+ }
82
+ return table
83
+ end
84
+
85
+ def make_overview_table
86
+ table = [:table, {:class => "fullwidth"}]
87
+ heading = make_heading([_("Overview"), "first", 2])
88
+ table.push(heading)
89
+ trs = []
90
+ trs << make_tr(_("Packages"), @dbm.get_npackages)
91
+ trs << make_tr(_("Contents"), @dbm.get_ncontents)
92
+ trs << make_tr(_("Indexed Contents"), @dbm.get_ncontents_indexed)
93
+ trs << make_tr(_("Binary Contents"), @dbm.get_ncontents - @dbm.get_ncontents_indexed)
94
+ trs << make_tr(_("Lines of Indexed Contents"), @dbm.get_nlines_indexed)
95
+ trs << make_tr(_("Indexed Keys"), @dbm.get_nwords)
96
+ trs << make_tr(_("Formats"), @dbm.get_nformats)
97
+ trs.each_with_index {|tr, i|
98
+ k = choose_tr_class(i)
99
+ tr.insert(1, {:class => k})
100
+ table.push(tr)
101
+ }
102
+ return table
103
+ end
104
+
105
+ def make_top_page
106
+ title = make_title( _("Statistics"))
107
+ content = [:div]
108
+ content.push(make_overview_table)
109
+ content.push(make_format_table)
110
+ status_line = make_status_line(_("Statistics"))
111
+ return title, status_line, content
112
+ end
113
+
114
+ def do_GET(request, response)
115
+ init_servlet(request, response)
116
+ log()
117
+
118
+ @path = make_path
119
+ title, status_line, content = make_top_page
120
+
121
+ html = make_html
122
+ head = [:head, title, make_script, *make_meta_and_css]
123
+ body = [:body]
124
+ body.push(make_h1)
125
+ body.push(make_search_form)
126
+ body.push(status_line)
127
+ body.push(content)
128
+ body.push(make_footer)
129
+ html.push(head)
130
+ html.push(body)
131
+ set_content_type_text_html
132
+ response.body = format_html(html)
133
+ end
134
+
135
+ GonzuiServlet.register(self)
136
+ end
137
+ end
@@ -0,0 +1,63 @@
1
+ #
2
+ # top.rb - top page 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 TopPageServlet < GonzuiAbstractServlet
14
+ def self.mount_point
15
+ ""
16
+ end
17
+
18
+ def validate_request
19
+ return if @request.path_info == "/" or @request.path_info.empty?
20
+ if @request.path_info == "/favicon.ico"
21
+ uri = make_doc_uri("favicon.ico")
22
+ @response.set_redirect(HTTPStatus::MovedPermanently, uri)
23
+ else
24
+ raise HTTPStatus::NotFound.new("not found")
25
+ end
26
+ assert_not_reached
27
+ end
28
+
29
+ def do_GET(request, response)
30
+ init_servlet(request, response)
31
+ validate_request
32
+ log()
33
+
34
+ title = make_title
35
+ html = make_html
36
+ head = [:head, title, make_script, *make_meta_and_css]
37
+ body = [:body]
38
+
39
+ content = [:div, {:class => "center"},
40
+ make_h1,
41
+ make_search_form(:central => true),
42
+ ]
43
+ footer = make_footer
44
+ summary = [
45
+ [:br],
46
+ sprintf(_("Searching %s packages of %s contents"),
47
+ commify(@dbm.get_npackages),
48
+ commify(@dbm.get_ncontents))
49
+ ]
50
+ footer.push(*summary)
51
+
52
+ content.push(footer)
53
+ body.push(content)
54
+ html.push(head)
55
+ html.push(body)
56
+ set_content_type_text_html
57
+ response.body = format_html(html)
58
+ end
59
+
60
+ GonzuiServlet.register(self)
61
+ end
62
+ end
63
+
@@ -0,0 +1,140 @@
1
+ #
2
+ # uri.rb - uri functions
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
+ QueryValue = Struct.new(:short_name, :default_value, :conversion_method)
14
+
15
+ module URIMaker
16
+ ParamTable = {
17
+ :display_language => QueryValue.new("dl", nil, :to_s),
18
+ :from => QueryValue.new("f", 0, :to_i),
19
+ :format => QueryValue.new("fm", "all", :to_s),
20
+ :grep_pattern => QueryValue.new("g", nil, :to_s),
21
+ :license => QueryValue.new("l", "all", :to_s),
22
+ :nresults_per_page => QueryValue.new("n", 10, :to_i),
23
+ :phrase_query => QueryValue.new("pq", nil, :to_s),
24
+ :basic_query => QueryValue.new("q", "", :to_s),
25
+ :target_type => QueryValue.new("tt", nil, :to_s),
26
+ }
27
+
28
+ def decompose_search_query(search_query)
29
+ options = {}
30
+ options[:basic_query] = search_query.string
31
+ options[:format] = search_query.format
32
+ options[:license] = search_query.license
33
+ return options
34
+ end
35
+
36
+ def get_default_query_value(long_name)
37
+ ParamTable[long_name]
38
+ end
39
+
40
+ def get_query_value(query, long_name)
41
+ qv = get_default_query_value(long_name)
42
+ assert(qv)
43
+ value = query[qv.short_name]
44
+ if value and not value.empty?
45
+ return value.send(qv.conversion_method)
46
+ else
47
+ return qv.default_value
48
+ end
49
+ end
50
+
51
+ def get_short_name(long_name)
52
+ qv = ParamTable[long_name]
53
+ raise "unknown variable name" if qv.nil?
54
+ return qv.short_name
55
+ end
56
+
57
+ def make_advanced_search_uri(search_query)
58
+ make_uri_general(AdvancedSearchServlet)
59
+ end
60
+
61
+ def make_doc_uri(path = nil)
62
+ make_uri_general(FileHandler, path)
63
+ end
64
+
65
+ def make_google_uri(search_query)
66
+ sprintf("http://www.google.com/search?q=%s",
67
+ HTTPUtils.escape_form(search_query.string_without_properties))
68
+ end
69
+
70
+ def make_lineno_uri(markup_uri, lineno)
71
+ sprintf("%s#l%d", markup_uri, lineno)
72
+ end
73
+
74
+ def make_markup_uri(path = "", search_query = nil, options = {})
75
+ if search_query
76
+ decompose_search_query(search_query).each {|k, v|
77
+ options[k] = v
78
+ }
79
+ end
80
+ return make_uri_with_options(MarkupServlet, path, options)
81
+ end
82
+
83
+ def make_search_uri(search_query, options = {})
84
+ options.merge!(decompose_search_query(search_query))
85
+ make_uri_with_options(SearchServlet, "", options)
86
+ end
87
+
88
+ def make_search_uri_partial(query_string)
89
+ sprintf("%s?%s=",
90
+ make_uri_general(SearchServlet),
91
+ get_short_name(:basic_query))
92
+ end
93
+
94
+ def make_source_uri(path = nil)
95
+ make_uri_general(SourceServlet, path)
96
+ end
97
+
98
+ def make_stat_uri(path = nil)
99
+ make_uri_general(StatisticsServlet, path)
100
+ end
101
+
102
+ def make_top_uri
103
+ make_uri_general(TopPageServlet)
104
+ end
105
+
106
+ def escape_path(path)
107
+ path.gsub(%r{[^A-Za-z0-9\-._~!$&'()*+,;=:@/]}) {
108
+ '%' + $&.unpack("H2")[0].upcase
109
+ }
110
+ end
111
+
112
+ def make_uri_general(klass, path = nil)
113
+ assert_non_nil(@config)
114
+ if path
115
+ return URI.path_join(@config.base_mount_point,
116
+ klass.mount_point,
117
+ escape_path(path))
118
+ else
119
+ return URI.path_join(@config.base_mount_point, klass.mount_point)
120
+ end
121
+ end
122
+
123
+ def make_uri_with_options(klass, path, options)
124
+ params = []
125
+ options.each {|name, value|
126
+ next if value.nil?
127
+ qv = get_default_query_value(name)
128
+ if qv and value != qv.default_value
129
+ param = sprintf("%s=%s", qv.short_name, HTTPUtils.escape_form(value.to_s))
130
+ params.push(param)
131
+ end
132
+ }
133
+ assert_non_nil(@config)
134
+ uri = URI.path_join(@config.base_mount_point, klass.mount_point)
135
+ uri = URI.path_join(uri, escape_path(path)) unless path.empty?
136
+ uri << "?" + params.join("&") unless params.empty?
137
+ return uri
138
+ end
139
+ end
140
+ end