gren 0.2.4 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|