gren 0.2.4 → 0.3.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.
- data/History.ja.txt +8 -0
- data/History.txt +10 -0
- data/Manifest.txt +18 -4
- data/Rakefile +6 -1
- data/bin/grenweb +11 -0
- data/lib/common/util.rb +3 -3
- data/lib/findgrep/findgrep.rb +46 -25
- data/lib/gren.rb +1 -1
- data/lib/grenweb/cli.rb +52 -0
- data/lib/grenweb/database.rb +179 -0
- data/lib/grenweb/grenweb.ru +35 -0
- data/lib/grenweb/grep.rb +52 -0
- data/lib/grenweb/help.rb +37 -0
- data/lib/grenweb/home.rb +37 -0
- data/lib/grenweb/html_renderer.rb +231 -0
- data/lib/grenweb/public/css/gren.css +63 -0
- data/lib/grenweb/public/images/gren-icon-mini.png +0 -0
- data/lib/grenweb/public/images/gren-icon.png +0 -0
- data/lib/grenweb/query.rb +82 -0
- data/lib/grenweb/searcher.rb +127 -0
- data/lib/grenweb/viewer.rb +53 -0
- data/lib/mkgrendb/mkgrendb.rb +15 -8
- data/test/test_gren.rb +1 -2
- data/test/test_gren_util.rb +33 -32
- data/test/test_grenweb_cli.rb +10 -0
- data/test/test_grenweb_html_renderer.rb +40 -0
- data/test/test_grenweb_query.rb +54 -0
- data/test/test_grenweb_searcher.rb +35 -0
- data/test/test_string_snip.rb +3 -1
- metadata +59 -15
- data/lib/gren/findgrep.rb +0 -215
- data/test/test_gren_cli.rb +0 -14
- data/test/test_grendb_cli.rb +0 -14
- data/test/test_mkgrendb_cli.rb +0 -14
data/History.ja.txt
CHANGED
data/History.txt
CHANGED
data/Manifest.txt
CHANGED
@@ -6,6 +6,7 @@ README.rdoc
|
|
6
6
|
Rakefile
|
7
7
|
bin/gren
|
8
8
|
bin/grendb
|
9
|
+
bin/grenweb
|
9
10
|
bin/mkgrendb
|
10
11
|
lib/common/display_util.rb
|
11
12
|
lib/common/grenfiletest.rb
|
@@ -17,8 +18,20 @@ lib/findgrep/findgrep.rb
|
|
17
18
|
lib/findgrep/result.rb
|
18
19
|
lib/gren.rb
|
19
20
|
lib/gren/cli.rb
|
20
|
-
lib/gren/findgrep.rb
|
21
21
|
lib/grendb/cli.rb
|
22
|
+
lib/grenweb/cli.rb
|
23
|
+
lib/grenweb/database.rb
|
24
|
+
lib/grenweb/grenweb.ru
|
25
|
+
lib/grenweb/grep.rb
|
26
|
+
lib/grenweb/help.rb
|
27
|
+
lib/grenweb/home.rb
|
28
|
+
lib/grenweb/html_renderer.rb
|
29
|
+
lib/grenweb/public/css/gren.css
|
30
|
+
lib/grenweb/public/images/gren-icon-mini.png
|
31
|
+
lib/grenweb/public/images/gren-icon.png
|
32
|
+
lib/grenweb/query.rb
|
33
|
+
lib/grenweb/searcher.rb
|
34
|
+
lib/grenweb/viewer.rb
|
22
35
|
lib/mkgrendb/cli.rb
|
23
36
|
lib/mkgrendb/mkgrendb.rb
|
24
37
|
rake_rdoc_custom.rb
|
@@ -26,9 +39,10 @@ script/console
|
|
26
39
|
script/destroy
|
27
40
|
script/generate
|
28
41
|
test/test_gren.rb
|
29
|
-
test/test_gren_cli.rb
|
30
42
|
test/test_gren_util.rb
|
31
|
-
test/
|
43
|
+
test/test_grenweb_cli.rb
|
44
|
+
test/test_grenweb_html_renderer.rb
|
45
|
+
test/test_grenweb_query.rb
|
46
|
+
test/test_grenweb_searcher.rb
|
32
47
|
test/test_helper.rb
|
33
|
-
test/test_mkgrendb_cli.rb
|
34
48
|
test/test_string_snip.rb
|
data/Rakefile
CHANGED
@@ -20,7 +20,12 @@ $hoe = Hoe.spec 'gren' do
|
|
20
20
|
self.rubyforge_name = self.name # TODO this is default value
|
21
21
|
|
22
22
|
# 必要とするgem
|
23
|
-
self.extra_deps = [
|
23
|
+
self.extra_deps = [
|
24
|
+
['termcolor','>= 1.2.0'],
|
25
|
+
['rroonga','>= 1.0.0'],
|
26
|
+
['rack','>=1.2.1'],
|
27
|
+
['launchy', '>=0.3.7']
|
28
|
+
]
|
24
29
|
|
25
30
|
# 本来はnewgemの中で設定されるべき(後で報告した方がいいかも)
|
26
31
|
self.extra_rdoc_files << "README.rdoc"
|
data/bin/grenweb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Created on 2010-10-10.
|
4
|
+
# Copyright (c) 2010. All rights reserved.
|
5
|
+
|
6
|
+
require 'rubygems'
|
7
|
+
require File.expand_path(File.dirname(__FILE__) + "/../lib/gren")
|
8
|
+
require "grenweb/cli"
|
9
|
+
|
10
|
+
Version = "0.3.0"
|
11
|
+
Grenweb::CLI.execute(STDOUT, ARGV)
|
data/lib/common/util.rb
CHANGED
@@ -70,7 +70,7 @@ module Gren
|
|
70
70
|
operator_start_index = group[0].size
|
71
71
|
limit = ALPHABET_DISP_NUM
|
72
72
|
|
73
|
-
print
|
73
|
+
print((array.size > limit) ? "| " : "↓ ")
|
74
74
|
|
75
75
|
counter = 0
|
76
76
|
array.each_with_index do |v, index|
|
@@ -78,13 +78,13 @@ module Gren
|
|
78
78
|
limit = OPERATOR_DISP_NUM
|
79
79
|
counter = 0
|
80
80
|
puts
|
81
|
-
print
|
81
|
+
print((array.size - index > limit) ? "| " : "↓ ")
|
82
82
|
end
|
83
83
|
|
84
84
|
if (counter >= limit)
|
85
85
|
counter = 0
|
86
86
|
puts
|
87
|
-
print
|
87
|
+
print((array.size - index > limit) ? "| " : "↓ ")
|
88
88
|
end
|
89
89
|
|
90
90
|
print v + ", "
|
data/lib/findgrep/findgrep.rb
CHANGED
@@ -10,6 +10,7 @@ require File.join(File.dirname(__FILE__), '../common/grensnip')
|
|
10
10
|
require 'groonga'
|
11
11
|
require File.join(File.dirname(__FILE__), '../common/util')
|
12
12
|
include Gren
|
13
|
+
require 'cgi'
|
13
14
|
|
14
15
|
module FindGrep
|
15
16
|
class FindGrep
|
@@ -29,8 +30,9 @@ module FindGrep
|
|
29
30
|
:noSnip,
|
30
31
|
:dbFile,
|
31
32
|
:groongaOnly,
|
32
|
-
:isMatchFile
|
33
|
-
|
33
|
+
:isMatchFile,
|
34
|
+
:dispHtml)
|
35
|
+
|
34
36
|
DEFAULT_OPTION = Option.new([],
|
35
37
|
[],
|
36
38
|
".",
|
@@ -47,8 +49,11 @@ module FindGrep
|
|
47
49
|
false,
|
48
50
|
nil,
|
49
51
|
false,
|
52
|
+
false,
|
50
53
|
false)
|
51
54
|
|
55
|
+
attr_reader :documents
|
56
|
+
|
52
57
|
def initialize(patterns, option)
|
53
58
|
@patterns = patterns
|
54
59
|
@option = option
|
@@ -59,6 +64,22 @@ module FindGrep
|
|
59
64
|
@ignoreFiles = strs2regs(option.ignoreFiles)
|
60
65
|
@ignoreDirs = strs2regs(option.ignoreDirs)
|
61
66
|
@result = Result.new(option.directory)
|
67
|
+
open_database if (@option.dbFile)
|
68
|
+
end
|
69
|
+
|
70
|
+
def open_database()
|
71
|
+
# データベース開く
|
72
|
+
dbfile = Pathname(File.expand_path(@option.dbFile))
|
73
|
+
|
74
|
+
if dbfile.exist?
|
75
|
+
Groonga::Database.open(dbfile.to_s)
|
76
|
+
puts "open : #{dbfile} open."
|
77
|
+
else
|
78
|
+
raise "error : #{dbfile.to_s} not found!!"
|
79
|
+
end
|
80
|
+
|
81
|
+
# ドキュメントを取
|
82
|
+
@documents = Groonga::Context.default["documents"]
|
62
83
|
end
|
63
84
|
|
64
85
|
def strs2regs(strs, ignore = false)
|
@@ -82,7 +103,7 @@ module FindGrep
|
|
82
103
|
|
83
104
|
@result.time_stop
|
84
105
|
|
85
|
-
|
106
|
+
if (!@option.isSilent && !@option.dispHtml)
|
86
107
|
if (@option.debugMode)
|
87
108
|
stdout.puts
|
88
109
|
stdout.puts "--- search --------"
|
@@ -108,21 +129,8 @@ module FindGrep
|
|
108
129
|
end
|
109
130
|
|
110
131
|
def searchFromDB(stdout, dir)
|
111
|
-
# データベース開く
|
112
|
-
dbfile = Pathname(File.expand_path(@option.dbFile))
|
113
|
-
|
114
|
-
if dbfile.exist?
|
115
|
-
Groonga::Database.open(dbfile.to_s)
|
116
|
-
puts "open : #{dbfile} open."
|
117
|
-
else
|
118
|
-
raise "error : #{dbfile.to_s} not found!!"
|
119
|
-
end
|
120
|
-
|
121
|
-
# ドキュメントを検索
|
122
|
-
documents = Groonga::Context.default["documents"]
|
123
|
-
|
124
132
|
# 全てのパターンを検索
|
125
|
-
table = documents.select do |record|
|
133
|
+
table = @documents.select do |record|
|
126
134
|
expression = nil
|
127
135
|
|
128
136
|
# キーワード
|
@@ -154,10 +162,11 @@ module FindGrep
|
|
154
162
|
end
|
155
163
|
|
156
164
|
# タイムスタンプでソート
|
157
|
-
records = table.sort([{:key => "
|
165
|
+
records = table.sort([{:key => "_score", :order => "descending"},
|
166
|
+
{:key => "timestamp", :order => "descending"}])
|
158
167
|
|
159
168
|
# データベースにヒット
|
160
|
-
stdout.puts "Found : #{records.size} records."
|
169
|
+
stdout.puts "Found : #{records.size} records." unless (@option.dispHtml)
|
161
170
|
|
162
171
|
# 検索にヒットしたファイルを実際に検索
|
163
172
|
records.each do |record|
|
@@ -316,13 +325,25 @@ module FindGrep
|
|
316
325
|
result, match_datas = match?(line)
|
317
326
|
|
318
327
|
if ( result )
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
328
|
+
unless (@option.dispHtml)
|
329
|
+
header = "#{path}:#{index + 1}:"
|
330
|
+
line = GrenSnip::snip(line, match_datas) unless (@option.noSnip)
|
331
|
+
|
332
|
+
unless (@option.colorHighlight)
|
333
|
+
stdout.puts header + line
|
334
|
+
else
|
335
|
+
stdout.puts HighLine::BLUE + header + HighLine::CLEAR + GrenSnip::coloring(line, match_datas)
|
336
|
+
end
|
324
337
|
else
|
325
|
-
|
338
|
+
line_no = index + 1
|
339
|
+
line = GrenSnip::snip(line, match_datas) unless (@option.noSnip)
|
340
|
+
|
341
|
+
stdout.puts <<EOF
|
342
|
+
<h2><a href="../::view#{path}">#{path}</a></h2>
|
343
|
+
<pre>
|
344
|
+
#{line_no} : #{CGI.escapeHTML(line)}
|
345
|
+
</pre>
|
346
|
+
EOF
|
326
347
|
end
|
327
348
|
|
328
349
|
unless match_file
|
data/lib/gren.rb
CHANGED
data/lib/grenweb/cli.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'optparse'
|
3
|
+
require 'rubygems'
|
4
|
+
require 'rack'
|
5
|
+
require 'fileutils'
|
6
|
+
require File.join(File.dirname(__FILE__), 'database')
|
7
|
+
require 'launchy'
|
8
|
+
|
9
|
+
module Grenweb
|
10
|
+
class CLI
|
11
|
+
def self.execute(stdout, arguments=[])
|
12
|
+
option = {
|
13
|
+
:Port => 9292,
|
14
|
+
:DbFile => ENV['GRENDB_DEFAULT_DB'],
|
15
|
+
}
|
16
|
+
|
17
|
+
opt = OptionParser.new("#{File.basename($0)}")
|
18
|
+
opt.on('--db [GREN_DB_FILE]', 'Search from the grendb database.') {|v| option[:DbFile] = v }
|
19
|
+
opt.on('-p', '--port PORT', 'use PORT (default: 9292)') {|v| option[:Port] = v }
|
20
|
+
opt.on('--no-browser', 'No launch browser.') {|v| option[:NoBrowser] = true }
|
21
|
+
opt.parse!(arguments)
|
22
|
+
|
23
|
+
# webサーバー起動
|
24
|
+
stdout.puts <<EOF
|
25
|
+
Start up grenweb !!
|
26
|
+
URL : http://localhost:#{option[:Port]}
|
27
|
+
DB : #{option[:DbFile]}
|
28
|
+
----------------------------------------
|
29
|
+
EOF
|
30
|
+
|
31
|
+
# 使用するデータベースの位置設定
|
32
|
+
Database.setup(option[:DbFile])
|
33
|
+
|
34
|
+
# サーバースクリプトのある場所へ移動
|
35
|
+
FileUtils.cd(File.dirname(__FILE__))
|
36
|
+
|
37
|
+
# ブラウザ起動
|
38
|
+
Launchy.open("http://localhost:#{option[:Port]}") unless (option[:NoBrowser])
|
39
|
+
|
40
|
+
# サーバー起動
|
41
|
+
Rack::Server.start(
|
42
|
+
:environment => "development",
|
43
|
+
:pid => nil,
|
44
|
+
:Port => option[:Port],
|
45
|
+
:Host => "0.0.0.0",
|
46
|
+
:AccessLog => [],
|
47
|
+
:config => "grenweb.ru"
|
48
|
+
)
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,179 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
#
|
3
|
+
# @file
|
4
|
+
# @brief Grenwebで使用するデータベース
|
5
|
+
# @author ongaeshi
|
6
|
+
# @date 2010/10/17
|
7
|
+
|
8
|
+
require 'groonga'
|
9
|
+
require 'pathname'
|
10
|
+
require 'singleton'
|
11
|
+
|
12
|
+
module Grenweb
|
13
|
+
class Database
|
14
|
+
include Singleton
|
15
|
+
|
16
|
+
def self.setup(dbFile)
|
17
|
+
@@dbFile = dbFile
|
18
|
+
end
|
19
|
+
|
20
|
+
def initialize
|
21
|
+
open(@@dbFile)
|
22
|
+
end
|
23
|
+
|
24
|
+
def open(dbFile)
|
25
|
+
dbfile = Pathname(File.expand_path(dbFile))
|
26
|
+
|
27
|
+
if dbfile.exist?
|
28
|
+
Groonga::Database.open(dbfile.to_s)
|
29
|
+
else
|
30
|
+
raise "error : #{dbfile.to_s} not found!!"
|
31
|
+
end
|
32
|
+
|
33
|
+
@documents = Groonga::Context.default["documents"]
|
34
|
+
end
|
35
|
+
|
36
|
+
def record(shortpath)
|
37
|
+
before = Time.now
|
38
|
+
table = @documents.select { |record| record.shortpath == shortpath }
|
39
|
+
elapsed = Time.now - before
|
40
|
+
return table.records[0], elapsed
|
41
|
+
end
|
42
|
+
|
43
|
+
def fileNum
|
44
|
+
@documents.select.size
|
45
|
+
end
|
46
|
+
|
47
|
+
def search(patterns, packages, fpaths, suffixs, page = 0, limit = -1)
|
48
|
+
before = Time.now
|
49
|
+
|
50
|
+
# 全てのパターンを検索
|
51
|
+
if (fpaths.include?("*"))
|
52
|
+
records, total_records = selectAll(page, limit)
|
53
|
+
else
|
54
|
+
records, total_records = searchMain(patterns, packages, fpaths, suffixs, page, limit)
|
55
|
+
end
|
56
|
+
|
57
|
+
# 検索にかかった時間
|
58
|
+
elapsed = Time.now - before
|
59
|
+
|
60
|
+
# 結果
|
61
|
+
return records, total_records, elapsed
|
62
|
+
end
|
63
|
+
|
64
|
+
def selectAll(page, limit)
|
65
|
+
table = @documents.select
|
66
|
+
|
67
|
+
# マッチ数
|
68
|
+
total_records = table.size
|
69
|
+
|
70
|
+
# 2010/10/29 ongaeshi
|
71
|
+
# 本当はこのようにgroongaAPIでソートしたいのだが上手くいかなかった
|
72
|
+
# # ファイル名順にソート
|
73
|
+
# records = table.sort([{:key => "shortpath", :order => "descending"}],
|
74
|
+
# :offset => page * limit,
|
75
|
+
# :limit => limit)
|
76
|
+
|
77
|
+
# ソート
|
78
|
+
records = table.records.sort_by{|record| record.shortpath.downcase }[page * limit, limit]
|
79
|
+
|
80
|
+
return records, total_records
|
81
|
+
end
|
82
|
+
|
83
|
+
def searchMain(patterns, packages, fpaths, suffixs, page, limit)
|
84
|
+
table = @documents.select do |record|
|
85
|
+
expression = nil
|
86
|
+
|
87
|
+
# キーワード
|
88
|
+
patterns.each do |word|
|
89
|
+
sub_expression = record.content =~ word
|
90
|
+
if expression.nil?
|
91
|
+
expression = sub_expression
|
92
|
+
else
|
93
|
+
expression &= sub_expression
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
# パッケージ(OR)
|
98
|
+
pe = package_expression(record, packages)
|
99
|
+
if (pe)
|
100
|
+
if expression.nil?
|
101
|
+
expression = pe
|
102
|
+
else
|
103
|
+
expression &= pe
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
# ファイルパス
|
108
|
+
fpaths.each do |word|
|
109
|
+
sub_expression = record.path =~ word
|
110
|
+
if expression.nil?
|
111
|
+
expression = sub_expression
|
112
|
+
else
|
113
|
+
expression &= sub_expression
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
# 拡張子(OR)
|
118
|
+
se = suffix_expression(record, suffixs)
|
119
|
+
if (se)
|
120
|
+
if expression.nil?
|
121
|
+
expression = se
|
122
|
+
else
|
123
|
+
expression &= se
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
# 検索式
|
128
|
+
expression
|
129
|
+
end
|
130
|
+
|
131
|
+
# マッチ数
|
132
|
+
total_records = table.size
|
133
|
+
|
134
|
+
# スコアとタイムスタンプでソート
|
135
|
+
records = table.sort([{:key => "_score", :order => "descending"},
|
136
|
+
{:key => "timestamp", :order => "descending"}],
|
137
|
+
:offset => page * limit,
|
138
|
+
:limit => limit)
|
139
|
+
|
140
|
+
return records, total_records
|
141
|
+
end
|
142
|
+
private :searchMain
|
143
|
+
|
144
|
+
def package_expression(record, packages)
|
145
|
+
sub = nil
|
146
|
+
|
147
|
+
# @todo 専用カラム package が欲しいところ
|
148
|
+
# でも今でもpackageはORとして機能してるからいいっちゃいい
|
149
|
+
packages.each do |word|
|
150
|
+
e = record.path =~ word
|
151
|
+
if sub.nil?
|
152
|
+
sub = e
|
153
|
+
else
|
154
|
+
sub |= e
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
sub
|
159
|
+
end
|
160
|
+
private :package_expression
|
161
|
+
|
162
|
+
def suffix_expression(record, suffixs)
|
163
|
+
sub = nil
|
164
|
+
|
165
|
+
suffixs.each do |word|
|
166
|
+
e = record.suffix =~ word
|
167
|
+
if sub.nil?
|
168
|
+
sub = e
|
169
|
+
else
|
170
|
+
sub |= e
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
sub
|
175
|
+
end
|
176
|
+
private :suffix_expression
|
177
|
+
|
178
|
+
end
|
179
|
+
end
|