gonzui 1.2
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/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/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/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/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 +291 -0
@@ -0,0 +1,100 @@
|
|
1
|
+
#
|
2
|
+
# license.rb - detect types of licenses with heuristics
|
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
|
+
LicenseRegistry = []
|
14
|
+
|
15
|
+
class License
|
16
|
+
def initialize(abbrev, name, regexp)
|
17
|
+
@abbrev = abbrev
|
18
|
+
@name = name
|
19
|
+
@regexp = regexp
|
20
|
+
@allow_later_p = false
|
21
|
+
end
|
22
|
+
attr_reader :abbrev
|
23
|
+
attr_reader :name
|
24
|
+
attr_reader :regexp
|
25
|
+
|
26
|
+
def allow_later
|
27
|
+
@allow_later_p = true
|
28
|
+
end
|
29
|
+
|
30
|
+
def allow_later?
|
31
|
+
@allow_later_p
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
LicenseRegistry << License.new("GPL1",
|
36
|
+
"GNU General Public License version 1",
|
37
|
+
/GNU General Public License .*?version 1/i
|
38
|
+
)
|
39
|
+
LicenseRegistry << License.new("GPL2",
|
40
|
+
"GNU General Public License version 2",
|
41
|
+
/GNU General Public License .*?version 2/i
|
42
|
+
)
|
43
|
+
LicenseRegistry << License.new("LGPL1",
|
44
|
+
"GNU Library Public License version 1",
|
45
|
+
/GNU Library Public License .*?version 1/i
|
46
|
+
)
|
47
|
+
LicenseRegistry << License.new("LGPL2",
|
48
|
+
"GNU Library Public License version 2",
|
49
|
+
/GNU Library Public License .*?version 2/i
|
50
|
+
)
|
51
|
+
LicenseRegistry << License.new("LGPL2.1",
|
52
|
+
"GNU Lesser Public License version 2.1",
|
53
|
+
/GNU Lesser Public License .*?version 2\.1/i
|
54
|
+
)
|
55
|
+
LicenseRegistry << License.new("Perl",
|
56
|
+
"Perl's License",
|
57
|
+
/under the same terms as Perl/i
|
58
|
+
)
|
59
|
+
LicenseRegistry << License.new("Ruby",
|
60
|
+
"Ruby's License",
|
61
|
+
/under the same terms as Ruby|Ruby's license/i
|
62
|
+
)
|
63
|
+
|
64
|
+
|
65
|
+
OtherLicense = License.new("Other", "Other License", "")
|
66
|
+
|
67
|
+
class LicenseDetector
|
68
|
+
def initialize(text)
|
69
|
+
len = 512
|
70
|
+
@chunk = (text[0, len] or "") # first 512 bytes
|
71
|
+
@chunk << (text[text.length - len, len] or "") # last 512 bytes
|
72
|
+
@chunk.gsub!(/[^\w.']+/, " ")
|
73
|
+
end
|
74
|
+
|
75
|
+
def allow_later?
|
76
|
+
regexp = /or (at your option )?any later version/i
|
77
|
+
return regexp.match(@chunk)
|
78
|
+
end
|
79
|
+
|
80
|
+
def detect
|
81
|
+
candidates = []
|
82
|
+
LicenseRegistry.each {|license|
|
83
|
+
if m = license.regexp.match(@chunk)
|
84
|
+
if allow_later?
|
85
|
+
license = license.clone
|
86
|
+
license.allow_later
|
87
|
+
end
|
88
|
+
candidates.push([m[0].length, license])
|
89
|
+
end
|
90
|
+
}
|
91
|
+
if candidates.empty?
|
92
|
+
return OtherLicense
|
93
|
+
else
|
94
|
+
license_of_shortest_match =
|
95
|
+
candidates.min {|a, b| a.first <=> b.first }.last
|
96
|
+
return license_of_shortest_match
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# -*- mode: ruby -*-
|
2
|
+
#
|
3
|
+
# logger.rb - logger implementation
|
4
|
+
#
|
5
|
+
# Copyright (C) 2004-2005 Satoru Takabayashi <satoru@namazu.org>
|
6
|
+
# All rights reserved.
|
7
|
+
# This is free software with ABSOLUTELY NO WARRANTY.
|
8
|
+
#
|
9
|
+
# You can redistribute it and/or modify it under the terms of
|
10
|
+
# the GNU General Public License version 2.
|
11
|
+
#
|
12
|
+
|
13
|
+
module Gonzui
|
14
|
+
class Logger
|
15
|
+
def initialize(out = nil, verbose_p = false)
|
16
|
+
@verbose_p = verbose_p
|
17
|
+
@out = case out
|
18
|
+
when String
|
19
|
+
File.open(out, "a")
|
20
|
+
when NilClass
|
21
|
+
STDERR
|
22
|
+
else
|
23
|
+
out
|
24
|
+
end
|
25
|
+
@out.sync = true
|
26
|
+
@monitor = nil
|
27
|
+
end
|
28
|
+
attr_writer :monitor
|
29
|
+
|
30
|
+
private
|
31
|
+
def puts_log(format, *arguments)
|
32
|
+
time = Time.now.strftime("%Y-%m-%dT%H:%M:%S")
|
33
|
+
message = ""
|
34
|
+
message << time << " " << sprintf(format, *arguments) << "\n"
|
35
|
+
@out << message
|
36
|
+
@monitor << message if @monitor
|
37
|
+
end
|
38
|
+
|
39
|
+
public
|
40
|
+
def log(format, *arguments)
|
41
|
+
puts_log(format, *arguments)
|
42
|
+
end
|
43
|
+
|
44
|
+
def vlog(format, *arguments)
|
45
|
+
puts_log(format, *arguments) if @verbose_p
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,177 @@
|
|
1
|
+
#
|
2
|
+
# monitor.rb - performance monitor
|
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 PerformanceMonitor
|
14
|
+
@@performance_counters = {}
|
15
|
+
|
16
|
+
def initialize
|
17
|
+
@start_time = Time.now
|
18
|
+
@elapsed_time = nil
|
19
|
+
@finished_p = false
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
def finish
|
24
|
+
@elapsed_time = Time.now - @start_time
|
25
|
+
@finished_p = true
|
26
|
+
end
|
27
|
+
|
28
|
+
def build_label(m, name)
|
29
|
+
case m
|
30
|
+
when Class
|
31
|
+
m.to_s + "#" + name.to_s
|
32
|
+
when Module
|
33
|
+
m.to_s + "." + name.to_s
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
public
|
38
|
+
def self.[] (label)
|
39
|
+
@@performance_counters[label]
|
40
|
+
end
|
41
|
+
|
42
|
+
def empty?
|
43
|
+
@@performance_counters.empty?
|
44
|
+
end
|
45
|
+
|
46
|
+
def profile(m, name)
|
47
|
+
label = build_label(m, name)
|
48
|
+
if !@@performance_counters[label]
|
49
|
+
@@performance_counters[label] = PerformanceCounter.new
|
50
|
+
case m
|
51
|
+
when Class
|
52
|
+
eval <<"End"
|
53
|
+
class #{m}
|
54
|
+
alias orig_#{name} #{name}
|
55
|
+
@@pc_#{name} = Gonzui::PerformanceMonitor["#{label}"]
|
56
|
+
# redefine with profiler
|
57
|
+
def #{name}(*args, &block)
|
58
|
+
@@pc_#{name}.enter
|
59
|
+
begin
|
60
|
+
orig_#{name}(*args, &block)
|
61
|
+
ensure
|
62
|
+
@@pc_#{name}.leave
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
End
|
67
|
+
when Module
|
68
|
+
eval <<"End"
|
69
|
+
module #{m}
|
70
|
+
alias orig_#{name} #{name}
|
71
|
+
module_function :orig_#{name}
|
72
|
+
# redefine with profiler
|
73
|
+
def #{name}(*args, &block)
|
74
|
+
pc = Gonzui::PerformanceMonitor["#{label}"]
|
75
|
+
pc.enter
|
76
|
+
begin
|
77
|
+
orig_#{name}(*args, &block)
|
78
|
+
ensure
|
79
|
+
pc.leave
|
80
|
+
end
|
81
|
+
end
|
82
|
+
module_function :#{name}
|
83
|
+
end
|
84
|
+
End
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def heading
|
90
|
+
return Gonzui::PerformanceCounter.heading
|
91
|
+
end
|
92
|
+
|
93
|
+
def format(primary_label, *labels)
|
94
|
+
finish unless @finished_p
|
95
|
+
|
96
|
+
label = build_label(*primary_label)
|
97
|
+
primary_pc = Gonzui::PerformanceMonitor[label]
|
98
|
+
return "" if primary_pc.nil?
|
99
|
+
|
100
|
+
summary = primary_pc.summary(label, 1, @elapsed_time)
|
101
|
+
labels.each {|label|
|
102
|
+
label = build_label(*label)
|
103
|
+
pc = Gonzui::PerformanceMonitor[label]
|
104
|
+
next if pc.nil?
|
105
|
+
summary << pc.summary(label, 2, @elapsed_time)
|
106
|
+
primary_pc.exclude(pc)
|
107
|
+
}
|
108
|
+
summary << primary_pc.rest_summary(:other, 2, @elapsed_time)
|
109
|
+
summary << "\n"
|
110
|
+
return summary
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
class PerformanceCounter
|
115
|
+
def initialize
|
116
|
+
@count = 0
|
117
|
+
@time_enter = 0
|
118
|
+
@time_total = 0
|
119
|
+
@time_subtotal = 0
|
120
|
+
@times_enter = 0
|
121
|
+
@times_total = Struct::Tms.new(0, 0, 0, 0)
|
122
|
+
@times_subtotal = Struct::Tms.new(0, 0, 0, 0)
|
123
|
+
end
|
124
|
+
|
125
|
+
def enter
|
126
|
+
@time_enter = Time.now
|
127
|
+
@times_enter = Process.times
|
128
|
+
@count += 1
|
129
|
+
end
|
130
|
+
|
131
|
+
def leave
|
132
|
+
@time_total += Time.now - @time_enter
|
133
|
+
times = Process.times
|
134
|
+
@times_total.utime += times.utime - @times_enter.utime
|
135
|
+
@times_total.stime += times.stime - @times_enter.stime
|
136
|
+
end
|
137
|
+
|
138
|
+
def time
|
139
|
+
@time_total
|
140
|
+
end
|
141
|
+
|
142
|
+
def utime
|
143
|
+
@times_total.utime
|
144
|
+
end
|
145
|
+
|
146
|
+
def stime
|
147
|
+
@times_total.stime
|
148
|
+
end
|
149
|
+
|
150
|
+
def exclude(pc)
|
151
|
+
@time_subtotal += pc.time
|
152
|
+
@times_subtotal.utime += pc.utime
|
153
|
+
@times_subtotal.stime += pc.stime
|
154
|
+
end
|
155
|
+
|
156
|
+
def self.heading
|
157
|
+
sprintf("%-32s %8s %6s %6s %6s\n",
|
158
|
+
"", "count", "utime", "stime", "real")
|
159
|
+
end
|
160
|
+
|
161
|
+
def summary(label, indent, elapsed)
|
162
|
+
sprintf("%-32s %8d %6.2fs %6.2fs %6.2fs (%6.2f%%)\n",
|
163
|
+
" " * indent + label, @count,
|
164
|
+
@times_total.utime, @times_total.stime,
|
165
|
+
@time_total, @time_total * 100 / elapsed)
|
166
|
+
end
|
167
|
+
|
168
|
+
def rest_summary(label, indent, elapsed)
|
169
|
+
time = @time_total - @time_subtotal
|
170
|
+
utime = @times_total.utime - @times_subtotal.utime
|
171
|
+
stime = @times_total.stime - @times_subtotal.stime
|
172
|
+
sprintf("%-32s %8s %6.2fs %6.2fs %6.2fs (%6.2f%%)\n",
|
173
|
+
" " * indent + label.to_s, '',
|
174
|
+
utime, stime, time, time * 100 / elapsed)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
@@ -0,0 +1,235 @@
|
|
1
|
+
#
|
2
|
+
# Ruby/ProgressBar - a text progress bar library
|
3
|
+
#
|
4
|
+
# Copyright (C) 2001-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
|
9
|
+
# of Ruby's license.
|
10
|
+
#
|
11
|
+
|
12
|
+
class ProgressBar
|
13
|
+
VERSION = "0.9"
|
14
|
+
|
15
|
+
def initialize(title, total, out = STDERR)
|
16
|
+
@title = title
|
17
|
+
@total = total
|
18
|
+
@out = out
|
19
|
+
@terminal_width = 80
|
20
|
+
@bar_mark = "o"
|
21
|
+
@current = 0
|
22
|
+
@previous = 0
|
23
|
+
@finished_p = false
|
24
|
+
@start_time = Time.now
|
25
|
+
@previous_time = @start_time
|
26
|
+
@title_width = 14
|
27
|
+
@format = "%-#{@title_width}s %3d%% %s %s"
|
28
|
+
@format_arguments = [:title, :percentage, :bar, :stat]
|
29
|
+
clear
|
30
|
+
show
|
31
|
+
end
|
32
|
+
attr_reader :title
|
33
|
+
attr_reader :current
|
34
|
+
attr_reader :total
|
35
|
+
attr_accessor :start_time
|
36
|
+
|
37
|
+
private
|
38
|
+
def fmt_bar
|
39
|
+
bar_width = do_percentage * @terminal_width / 100
|
40
|
+
sprintf("|%s%s|",
|
41
|
+
@bar_mark * bar_width,
|
42
|
+
" " * (@terminal_width - bar_width))
|
43
|
+
end
|
44
|
+
|
45
|
+
def fmt_percentage
|
46
|
+
do_percentage
|
47
|
+
end
|
48
|
+
|
49
|
+
def fmt_stat
|
50
|
+
if @finished_p then elapsed else eta end
|
51
|
+
end
|
52
|
+
|
53
|
+
def fmt_stat_for_file_transfer
|
54
|
+
if @finished_p then
|
55
|
+
sprintf("%s %s %s", bytes, transfer_rate, elapsed)
|
56
|
+
else
|
57
|
+
sprintf("%s %s %s", bytes, transfer_rate, eta)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def fmt_title
|
62
|
+
@title[0,(@title_width - 1)] + ":"
|
63
|
+
end
|
64
|
+
|
65
|
+
def convert_bytes(bytes)
|
66
|
+
if bytes < 1024
|
67
|
+
sprintf("%6dB", bytes)
|
68
|
+
elsif bytes < 1024 * 1000 # 1000kb
|
69
|
+
sprintf("%5.1fKB", bytes.to_f / 1024)
|
70
|
+
elsif bytes < 1024 * 1024 * 1000 # 1000mb
|
71
|
+
sprintf("%5.1fMB", bytes.to_f / 1024 / 1024)
|
72
|
+
else
|
73
|
+
sprintf("%5.1fGB", bytes.to_f / 1024 / 1024 / 1024)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def transfer_rate
|
78
|
+
bytes_per_second = @current.to_f / (Time.now - @start_time)
|
79
|
+
sprintf("%s/s", convert_bytes(bytes_per_second))
|
80
|
+
end
|
81
|
+
|
82
|
+
def bytes
|
83
|
+
convert_bytes(@current)
|
84
|
+
end
|
85
|
+
|
86
|
+
def format_time(t)
|
87
|
+
t = t.to_i
|
88
|
+
sec = t % 60
|
89
|
+
min = (t / 60) % 60
|
90
|
+
hour = t / 3600
|
91
|
+
sprintf("%02d:%02d:%02d", hour, min, sec);
|
92
|
+
end
|
93
|
+
|
94
|
+
# ETA stands for Estimated Time of Arrival.
|
95
|
+
def eta
|
96
|
+
if @current == 0
|
97
|
+
"ETA: --:--:--"
|
98
|
+
else
|
99
|
+
elapsed = Time.now - @start_time
|
100
|
+
eta = elapsed * @total / @current - elapsed;
|
101
|
+
sprintf("ETA: %s", format_time(eta))
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def elapsed
|
106
|
+
elapsed = Time.now - @start_time
|
107
|
+
sprintf("Time: %s", format_time(elapsed))
|
108
|
+
end
|
109
|
+
|
110
|
+
def eol
|
111
|
+
if @finished_p then "\n" else "\r" end
|
112
|
+
end
|
113
|
+
|
114
|
+
def do_percentage
|
115
|
+
if @total.zero?
|
116
|
+
100
|
117
|
+
else
|
118
|
+
@current * 100 / @total
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def get_width
|
123
|
+
# FIXME: I don't know how portable it is.
|
124
|
+
default_width = 80
|
125
|
+
begin
|
126
|
+
tiocgwinsz = 0x5413
|
127
|
+
data = [0, 0, 0, 0].pack("SSSS")
|
128
|
+
if @out.ioctl(tiocgwinsz, data) >= 0 then
|
129
|
+
rows, cols, xpixels, ypixels = data.unpack("SSSS")
|
130
|
+
if cols >= 0 then cols else default_width end
|
131
|
+
else
|
132
|
+
default_width
|
133
|
+
end
|
134
|
+
rescue Exception
|
135
|
+
default_width
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
def show
|
140
|
+
arguments = @format_arguments.map {|method|
|
141
|
+
method = sprintf("fmt_%s", method)
|
142
|
+
send(method)
|
143
|
+
}
|
144
|
+
line = sprintf(@format, *arguments)
|
145
|
+
|
146
|
+
width = get_width
|
147
|
+
if line.length == width - 1
|
148
|
+
@out.print(line + eol)
|
149
|
+
elsif line.length >= width
|
150
|
+
@terminal_width = [@terminal_width - (line.length - width + 1), 0].max
|
151
|
+
if @terminal_width == 0 then @out.print(line + eol) else show end
|
152
|
+
else # line.length < width - 1
|
153
|
+
@terminal_width += width - line.length + 1
|
154
|
+
show
|
155
|
+
end
|
156
|
+
@previous_time = Time.now
|
157
|
+
end
|
158
|
+
|
159
|
+
def show_if_needed
|
160
|
+
if @total.zero?
|
161
|
+
cur_percentage = 100
|
162
|
+
prev_percentage = 0
|
163
|
+
else
|
164
|
+
cur_percentage = (@current * 100 / @total).to_i
|
165
|
+
prev_percentage = (@previous * 100 / @total).to_i
|
166
|
+
end
|
167
|
+
|
168
|
+
# Use "!=" instead of ">" to support negative changes
|
169
|
+
if cur_percentage != prev_percentage ||
|
170
|
+
Time.now - @previous_time >= 1 || @finished_p
|
171
|
+
show
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
public
|
176
|
+
def clear
|
177
|
+
@out.print "\r"
|
178
|
+
@out.print(" " * (get_width - 1))
|
179
|
+
@out.print "\r"
|
180
|
+
end
|
181
|
+
|
182
|
+
def finish
|
183
|
+
@current = @total
|
184
|
+
@finished_p = true
|
185
|
+
show
|
186
|
+
end
|
187
|
+
|
188
|
+
def finished?
|
189
|
+
@finished_p
|
190
|
+
end
|
191
|
+
|
192
|
+
def file_transfer_mode
|
193
|
+
@format_arguments = [:title, :percentage, :bar, :stat_for_file_transfer]
|
194
|
+
end
|
195
|
+
|
196
|
+
def format= (format)
|
197
|
+
@format = format
|
198
|
+
end
|
199
|
+
|
200
|
+
def format_arguments= (arguments)
|
201
|
+
@format_arguments = arguments
|
202
|
+
end
|
203
|
+
|
204
|
+
def halt
|
205
|
+
@finished_p = true
|
206
|
+
show
|
207
|
+
end
|
208
|
+
|
209
|
+
def inc(step = 1)
|
210
|
+
@current += step
|
211
|
+
@current = @total if @current > @total
|
212
|
+
show_if_needed
|
213
|
+
@previous = @current
|
214
|
+
end
|
215
|
+
|
216
|
+
def set(count)
|
217
|
+
if count < 0 || count > @total
|
218
|
+
raise "invalid count: #{count} (total: #{@total})"
|
219
|
+
end
|
220
|
+
@current = count
|
221
|
+
show_if_needed
|
222
|
+
@previous = @current
|
223
|
+
end
|
224
|
+
|
225
|
+
def inspect
|
226
|
+
"#<ProgressBar:#{@current}/#{@total}>"
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
class ReversedProgressBar < ProgressBar
|
231
|
+
def do_percentage
|
232
|
+
100 - super
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|