gren 0.3.2 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. data/.gitignore +17 -0
  2. data/Gemfile +7 -0
  3. data/{History.ja.txt → HISTORY.ja.md} +41 -15
  4. data/HISTORY.md +92 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.ja.md +57 -0
  7. data/README.md +51 -0
  8. data/Rakefile +9 -39
  9. data/bin/gren +2 -7
  10. data/gren.gemspec +21 -0
  11. data/lib/gren.rb +3 -3
  12. data/lib/gren/cli.rb +13 -10
  13. data/lib/{common → gren/common}/grenfiletest.rb +0 -0
  14. data/lib/{common → gren/common}/grensnip.rb +1 -1
  15. data/lib/{common → gren/common}/platform.rb +0 -0
  16. data/lib/{common → gren/common}/string_snip.rb +0 -0
  17. data/lib/{common → gren/common}/util.rb +16 -10
  18. data/lib/{findgrep → gren/findgrep}/findgrep.rb +47 -143
  19. data/lib/{findgrep → gren/findgrep}/result.rb +1 -1
  20. data/lib/gren/version.rb +3 -0
  21. data/test/data/aaa.txt +1 -0
  22. data/test/data/abc.rb +8 -0
  23. data/test/data/bbb.txt +1 -0
  24. data/test/data/ccc.c +1 -0
  25. data/test/data/sub/ccc.txt +1 -0
  26. data/test/test_cli.rb +80 -0
  27. data/test/test_gren.rb +10 -10
  28. data/test/test_gren_util.rb +3 -2
  29. data/test/test_string_snip.rb +31 -31
  30. metadata +67 -177
  31. data/History.txt +0 -66
  32. data/Manifest.txt +0 -48
  33. data/PostInstall.txt +0 -7
  34. data/README.rdoc +0 -181
  35. data/bin/grendb +0 -11
  36. data/bin/grenweb +0 -11
  37. data/bin/mkgrendb +0 -11
  38. data/lib/common/display_util.rb +0 -62
  39. data/lib/grendb/cli.rb +0 -41
  40. data/lib/grenweb/cli.rb +0 -52
  41. data/lib/grenweb/database.rb +0 -179
  42. data/lib/grenweb/grenweb.ru +0 -35
  43. data/lib/grenweb/grep.rb +0 -52
  44. data/lib/grenweb/help.rb +0 -39
  45. data/lib/grenweb/home.rb +0 -39
  46. data/lib/grenweb/html_renderer.rb +0 -243
  47. data/lib/grenweb/public/css/gren.css +0 -63
  48. data/lib/grenweb/public/images/gren-icon-mini.png +0 -0
  49. data/lib/grenweb/public/images/gren-icon.png +0 -0
  50. data/lib/grenweb/query.rb +0 -82
  51. data/lib/grenweb/searcher.rb +0 -129
  52. data/lib/grenweb/viewer.rb +0 -51
  53. data/lib/mkgrendb/cli.rb +0 -49
  54. data/lib/mkgrendb/mkgrendb.rb +0 -230
  55. data/rake_rdoc_custom.rb +0 -13
  56. data/script/console +0 -10
  57. data/script/destroy +0 -14
  58. data/script/generate +0 -14
  59. data/test/test_grenweb_cli.rb +0 -10
  60. data/test/test_grenweb_html_renderer.rb +0 -41
  61. data/test/test_grenweb_query.rb +0 -54
  62. data/test/test_grenweb_searcher.rb +0 -35
@@ -1,63 +0,0 @@
1
- body {
2
- }
3
-
4
- div.header {
5
- }
6
-
7
- div.footer {
8
- }
9
-
10
- div.header_home {
11
- font-size: 170%;
12
- }
13
-
14
- div.footer_home {
15
- font-size: 85%;
16
- margin-top: 3em;
17
- }
18
-
19
- div.search-summary {
20
- border-color:#F4CA3F;
21
- background-color:#FEFFF0;
22
- border-top-style:solid;
23
- border-top-width:1px;
24
- border-bottom-style:solid;
25
- border-bottom-width:1px;
26
- margin-bottom:1em;
27
- margin-top:1em;
28
- padding-bottom:5px;
29
- padding-top:5px;
30
- padding-left:5px;
31
- }
32
-
33
- dt.result-record {
34
- font-size: 105%;
35
- }
36
-
37
- pre.lines {
38
- }
39
-
40
- div.pagination {
41
- background-color:#FEFFF0;
42
- text-align: center;
43
- margin-bottom: 20px;
44
- }
45
-
46
- pre {
47
- border: 1px solid #dedede;
48
- margin-bottom: 5px;
49
- padding-left: 5px;
50
- background-color: #fdfdfd;
51
- font-weight: inherit;
52
- margin-top: 5px;
53
- padding-top: 5px;
54
- padding-bottom: 5px;
55
- }
56
-
57
- span.keyword {
58
- font-weight: bold;
59
- }
60
-
61
- font.version {
62
- font-size: 35%;
63
- }
@@ -1,82 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- #
3
- # @file
4
- # @brief クエリーの解析
5
- # @author ongaeshi
6
- # @date 2010/10/21
7
-
8
- require 'rubygems'
9
- require 'rack'
10
-
11
- module Grenweb
12
- class Query
13
- include Rack::Utils
14
- attr_reader :query_string
15
-
16
- OPTIONS = [
17
- ['package', 'p'],
18
- ['filepath', 'fpath', 'f'],
19
- ['suffix', 's'],
20
- ]
21
-
22
- def initialize(request)
23
- @query_string = unescape(request.path_info.gsub(/\A\/|\/\z/, ''))
24
- init_hash
25
- parse
26
- end
27
-
28
- def escape_html
29
- Rack::Utils::escape_html(@query_string)
30
- end
31
-
32
- def empty?
33
- keywords.size == 0 && packages.size == 0 && fpaths.size == 0 && suffixs.size == 0
34
- end
35
-
36
- def keywords
37
- @hash['keywords']
38
- end
39
-
40
- def packages
41
- calc_param(0)
42
- end
43
-
44
- def fpaths
45
- calc_param(1)
46
- end
47
-
48
- def suffixs
49
- calc_param(2)
50
- end
51
-
52
- private
53
-
54
- def calc_param(index)
55
- OPTIONS[index].inject([]){|result, item| result.concat @hash[item] }
56
- end
57
-
58
- def init_hash
59
- @hash = {}
60
- @hash['keywords'] = []
61
-
62
- OPTIONS.flatten.each do |key|
63
- @hash[key] = []
64
- end
65
- end
66
-
67
- def parse
68
- kp = OPTIONS.flatten.join('|')
69
- parts = @query_string.scan(/(?:(#{kp}):)?(?:"(.+)"|(\S+))/)
70
-
71
- parts.each do |key, quoted_value, value|
72
- text = quoted_value || value
73
- unless (key)
74
- @hash['keywords'] << text
75
- else
76
- @hash[key] << text
77
- end
78
- end
79
- end
80
- end
81
- end
82
-
@@ -1,129 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- #
3
- # @file
4
- # @brief 検索処理本体
5
- # @author ongaeshi
6
- # @date 2010/10/13
7
-
8
- require 'rack'
9
- require File.join(File.dirname(__FILE__), 'database')
10
- require File.join(File.dirname(__FILE__), 'html_renderer')
11
- require File.join(File.dirname(__FILE__), 'query')
12
-
13
- module Grenweb
14
- class Searcher
15
- include Rack::Utils
16
-
17
- def initialize
18
- end
19
-
20
- def call(env)
21
- @request = Rack::Request.new(env)
22
- @query = Query.new(@request)
23
-
24
- @response = Rack::Response.new
25
- @response["Content-Type"] = "text/html; charset=UTF-8"
26
-
27
- @nth = 3 # マッチした行の前後何行を表示するか
28
-
29
- @rendeler = HTMLRendeler.new(@request.script_name + '/..')
30
-
31
- if @request.post? or @request['query']
32
- post_request
33
- else
34
- search
35
- end
36
- end
37
-
38
- private
39
-
40
- def post_request
41
- query = @request['query'] || ''
42
- if query.empty?
43
- @request.path_info = "/"
44
- else
45
- @request.path_info = "/#{escape(query)}/"
46
- end
47
- @response.redirect(@request.url.split(/\?/, 2)[0])
48
- @response.to_a
49
- end
50
-
51
- def search
52
- render_header
53
- render_search_box
54
- render_search_result
55
- render_footer
56
- @response.to_a
57
- end
58
-
59
- def render_header
60
- @response.write @rendeler.header("gren : #{@query.escape_html}", "gren")
61
- end
62
-
63
- def render_search_box
64
- @response.write @rendeler.search_box(@query.escape_html)
65
- end
66
-
67
- def render_search_result
68
- if @query.empty?
69
- @response.write @rendeler.empty_summary
70
- else
71
- records, total_records, elapsed = Database.instance.search(@query.keywords, @query.packages, @query.fpaths, @query.suffixs, calcPage, calcLimit)
72
- render_search_summary(records, total_records, elapsed)
73
- records.each { |record| @response.write(@rendeler.result_record(record, @query.keywords, @nth)) }
74
- render_pagination(calcPage, total_records)
75
- end
76
- end
77
-
78
- def render_search_summary(records, total_records, elapsed)
79
- pageStart = calcPage * calcLimit
80
- @response.write @rendeler.search_summary(@query.query_string,
81
- total_records,
82
- (total_records.zero? ? 0 : pageStart + 1)..(pageStart + records.size),
83
- elapsed)
84
- end
85
-
86
- def render_pagination(page, total_records)
87
- return if @query.empty?
88
- return if total_records < calcLimit
89
-
90
- last_page = (total_records / calcLimit.to_f).ceil
91
- @response.write("<div class='pagination'>\n")
92
- if page > 0
93
- @response.write(@rendeler.pagination_link(page - 1, "<<"))
94
- end
95
- last_page.times do |i|
96
- if i == page
97
- @response.write(@rendeler.pagination_span(i))
98
- else
99
- @response.write(@rendeler.pagination_link(i, i))
100
- end
101
- end
102
- if page < (last_page - 1)
103
- @response.write(@rendeler.pagination_link(page + 1, ">>"))
104
- end
105
- @response.write("</div>\n")
106
- end
107
-
108
- def render_footer
109
- @response.write @rendeler.footer
110
- end
111
-
112
- private
113
-
114
- # 1ページに表示する最大レコードを計算
115
- def calcLimit
116
- if @query.keywords.size == 0
117
- 100
118
- else
119
- 20
120
- end
121
- end
122
-
123
- # 現在ページを計算
124
- def calcPage
125
- (@request['page'] || 0).to_i
126
- end
127
- end
128
- end
129
-
@@ -1,51 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- #
3
- # @file
4
- # @brief ソースコードを表示する
5
- # @author ongaeshi
6
- # @date 2010/10/13
7
-
8
- require 'rack'
9
- require File.join(File.dirname(__FILE__), 'database')
10
- require File.join(File.dirname(__FILE__), 'html_renderer')
11
-
12
- module Grenweb
13
- class Viewer
14
- include Rack::Utils
15
-
16
- def initialize
17
- end
18
-
19
- def call(env)
20
- @request = Rack::Request.new(env)
21
- @response = Rack::Response.new
22
- @response["Content-Type"] = "text/html; charset=UTF-8"
23
-
24
- record, elapsed = Database.instance.record(req2query)
25
-
26
- @rendeler = HTMLRendeler.new(@request.script_name + '/..')
27
-
28
- if (record)
29
- @response.write @rendeler.header("gren : #{record.shortpath}", "gren")
30
- @response.write @rendeler.search_box("")
31
- @response.write @rendeler.view_summary(record.shortpath, elapsed)
32
- @response.write @rendeler.record_content(record)
33
- else
34
- @response.write @rendeler.header("gren : not found.", "gren")
35
- @response.write @rendeler.search_box("")
36
- @response.write @rendeler.empty_summary
37
- end
38
- @response.write @rendeler.footer
39
-
40
- @response.to_a
41
- end
42
-
43
- private
44
-
45
- def req2query
46
- p @request.path_info
47
- unescape(@request.path_info.gsub(/\A\/|\/z/, ''))
48
- end
49
-
50
- end
51
- end
@@ -1,49 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- require 'optparse'
3
- require File.join(File.dirname(__FILE__), 'mkgrendb')
4
-
5
- module Mkgrendb
6
- class CLI
7
- def self.execute(stdout, arguments=[])
8
- input_yamls = []
9
- isDump = false
10
- isFull = false
11
- isDelete = false
12
- isReport = false
13
-
14
- opt = OptionParser.new "#{File.basename($0)} INPUT_YAML1 [INPUT_YAML2 ...]"
15
- opt.on('--ddb', "--default-db", "Create or Update default DB. (Plase set ENV['GRENDB_DEFAULT_DB'])") {|v| input_yamls << ENV['GRENDB_DEFAULT_DB']}
16
- opt.on('--full', "Full update DB. (Delete and create)") {|v| isFull = true }
17
- opt.on('--delete', "Delete DB. (Not delete yaml)") {|v| isDelete = true }
18
- opt.on('--dump', "Dump DB.") {|v| isDump = true }
19
- opt.on('--report', "Database Report.") {|v| isReport = true }
20
- opt.parse!(arguments)
21
-
22
- input_yamls.concat arguments
23
-
24
- if (input_yamls.size >= 1)
25
- input_yamls.each do |input_yaml|
26
- obj = Mkgrendb.new(input_yaml)
27
-
28
- if (isFull)
29
- obj.full
30
- stdout.puts
31
- elsif (isDelete)
32
- obj.delete
33
- stdout.puts
34
- elsif (isDump)
35
- obj.dump
36
- elsif (isReport)
37
- obj.report
38
- else
39
- obj.update
40
- stdout.puts
41
- end
42
-
43
- end
44
- else
45
- stdout.puts opt.help
46
- end
47
- end
48
- end
49
- end
@@ -1,230 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
-
3
- require 'yaml'
4
- require 'pathname'
5
- require 'rubygems'
6
- require 'groonga'
7
- require 'fileutils'
8
- require File.join(File.dirname(__FILE__), '../common/grenfiletest')
9
- require File.join(File.dirname(__FILE__), '../common/util')
10
- include Gren
11
-
12
- module Mkgrendb
13
- class Mkgrendb
14
- def initialize(input)
15
- input = File.expand_path(input)
16
- @input_yaml = input.sub(/\.db$/, ".yaml")
17
- @output_db = input.sub(/\.yaml$/, ".db")
18
- puts "input_yaml : #{@input_yaml} found."
19
- @src = YAML.load(open(@input_yaml).read())
20
- @file_count = 0
21
- @add_count = 0
22
- @update_count = 0
23
- @start_time = Time.now
24
- end
25
-
26
- def update
27
- db_create(@output_db)
28
- db_open(@output_db)
29
- @src["directory"].each do |dir|
30
- dir = File.expand_path(dir)
31
-
32
- if (!FileTest.exist?(dir))
33
- puts "[WARNING] : #{dir} (Not found, skip)"
34
- elsif (FileTest.directory? dir)
35
- db_add_dir(dir)
36
- else
37
- db_add_file(STDOUT, dir, File.basename(dir))
38
- end
39
- end
40
- @end_time = Time.now
41
- print_result
42
- end
43
-
44
- def delete
45
- db_delete(@output_db)
46
- end
47
-
48
- def full
49
- delete
50
- update
51
- end
52
-
53
- def time
54
- @end_time - @start_time
55
- end
56
-
57
- def print_result
58
- puts
59
- puts "input_yaml : #{@input_yaml} (#{Util::time_s(time)})"
60
- puts "output_db : #{@output_db}*"
61
- puts "files : #{@file_count}"
62
- puts "add : #{@add_count}"
63
- puts "update : #{@update_count}"
64
- end
65
-
66
- def dump()
67
- db_open(@output_db)
68
-
69
- documents = Groonga::Context.default["documents"]
70
- records = documents.select
71
- records.each do |record|
72
- p record
73
- puts "path : #{record.path}"
74
- puts "shortpath : #{record.shortpath}"
75
- puts "suffix : #{record.suffix}"
76
- puts "timestamp : #{record.timestamp.strftime('%Y/%m/%d %H:%M:%S')}"
77
- puts "content :", record.content ? record.content[0..64] : nil
78
- puts
79
- end
80
- end
81
-
82
- def db_create(filename)
83
- dbfile = Pathname(File.expand_path(filename))
84
- dbdir = dbfile.dirname
85
- dbdir.mkpath unless dbdir.exist?
86
-
87
- unless dbfile.exist?
88
- Groonga::Database.create(:path => dbfile.to_s)
89
- Groonga::Schema.define do |schema|
90
- schema.create_table("documents") do |table|
91
- table.string("path")
92
- table.string("shortpath")
93
- table.text("content")
94
- table.time("timestamp")
95
- table.text("suffix")
96
- end
97
-
98
- schema.create_table("terms",
99
- :type => :patricia_trie,
100
- :key_normalize => true,
101
- :default_tokenizer => "TokenBigram") do |table|
102
- table.index("documents.path", :with_position => true)
103
- table.index("documents.shortpath", :with_position => true)
104
- table.index("documents.content", :with_position => true)
105
- table.index("documents.suffix", :with_position => true)
106
- end
107
- end
108
- puts "create : #{filename} created."
109
- else
110
- puts "message : #{filename} already exist."
111
- end
112
- end
113
- private :db_create
114
-
115
- def db_delete(filename)
116
- raise "Illegal file name : #{filename}." unless filename =~ /\.db$/
117
- Dir.glob("#{filename}*").each do |f|
118
- puts "delete : #{f}"
119
- FileUtils.rm_r(f)
120
- end
121
- end
122
- private :db_delete
123
-
124
- def db_open(filename)
125
- dbfile = Pathname(File.expand_path(filename))
126
-
127
- if dbfile.exist?
128
- Groonga::Database.open(dbfile.to_s)
129
- puts "open : #{dbfile} open."
130
- else
131
- raise "error : #{dbfile.to_s} not found!!"
132
- end
133
- end
134
- private :db_open
135
-
136
- def db_add_dir(dirname)
137
- searchDirectory(STDOUT, dirname, File.basename(dirname), 0)
138
- end
139
- private :db_add_dir
140
-
141
- def db_add_file(stdout, filename, shortpath)
142
- # 格納するデータ
143
- values = {
144
- :path => filename,
145
- :shortpath => shortpath,
146
- :content => nil,
147
- :timestamp => File.mtime(filename),
148
- :suffix => File::extname(filename),
149
- }
150
-
151
- # 検索するデータベース
152
- documents = Groonga::Context.default["documents"]
153
-
154
- # 既に登録されているファイルならばそれを上書き、そうでなければ新規レコードを作成
155
- _documents = documents.select do |record|
156
- record["path"] == values[:path]
157
- end
158
-
159
- isNewFile = false
160
-
161
- if _documents.size.zero?
162
- document = documents.add
163
- isNewFile = true
164
- else
165
- document = _documents.to_a[0].key
166
- end
167
-
168
- # タイムスタンプが新しければデータベースに格納
169
- if (document[:timestamp] < values[:timestamp])
170
- # 実際に使うタイミングでファイルの内容を読み込み
171
- values[:content] = open(filename).read
172
-
173
- # データベースに格納
174
- values.each do |key, value|
175
- if (key == :path)
176
- if (isNewFile)
177
- @add_count += 1
178
- puts "add_file : #{value}"
179
- else
180
- @update_count += 1
181
- puts "update : #{value}"
182
- end
183
- end
184
- document[key] = value
185
- end
186
- end
187
-
188
- end
189
-
190
- def searchDirectory(stdout, dir, shortdir, depth)
191
- Dir.foreach(dir) do |name|
192
- next if (name == '.' || name == '..')
193
-
194
- fpath = File.join(dir,name)
195
- shortpath = File.join(shortdir,name)
196
-
197
- # 除外ディレクトリならばパス
198
- next if ignoreDir?(fpath)
199
-
200
- # 読み込み不可ならばパス
201
- next unless FileTest.readable?(fpath)
202
-
203
- # ファイルならば中身を探索、ディレクトリならば再帰
204
- case File.ftype(fpath)
205
- when "directory"
206
- searchDirectory(stdout, fpath, shortpath, depth + 1)
207
- when "file"
208
- unless ignoreFile?(fpath)
209
- db_add_file(stdout, fpath, shortpath)
210
- @file_count += 1
211
- puts "file_count : #{@file_count}" if (@file_count % 100 == 0)
212
- end
213
- end
214
- end
215
- end
216
-
217
- def ignoreDir?(fpath)
218
- FileTest.directory?(fpath) &&
219
- GrenFileTest::ignoreDir?(fpath)
220
- end
221
- private :ignoreDir?
222
-
223
- def ignoreFile?(fpath)
224
- GrenFileTest::ignoreFile?(fpath) ||
225
- GrenFileTest::binary?(fpath)
226
- end
227
- private :ignoreFile?
228
-
229
- end
230
- end