milkode 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/Gemfile +12 -0
- data/Gemfile.lock +18 -0
- data/HISTORY.rdoc +5 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +19 -0
- data/Rakefile +78 -0
- data/VERSION +1 -0
- data/bin/cdv +6 -0
- data/bin/cdview +10 -0
- data/bin/milk +10 -0
- data/lib/milkode/cdstk/cdstk.rb +508 -0
- data/lib/milkode/cdstk/cdstk_yaml.rb +106 -0
- data/lib/milkode/cdstk/cli_cdstk.rb +103 -0
- data/lib/milkode/cdstk/cli_cdstksub.rb +102 -0
- data/lib/milkode/cdview/cli_cdview.rb +43 -0
- data/lib/milkode/cdweb/app.rb +136 -0
- data/lib/milkode/cdweb/cli_cdweb.rb +111 -0
- data/lib/milkode/cdweb/config.ru +3 -0
- data/lib/milkode/cdweb/lib/coderay_wrapper.rb +94 -0
- data/lib/milkode/cdweb/lib/command.rb +67 -0
- data/lib/milkode/cdweb/lib/database.rb +260 -0
- data/lib/milkode/cdweb/lib/grep.rb +68 -0
- data/lib/milkode/cdweb/lib/mkurl.rb +56 -0
- data/lib/milkode/cdweb/lib/query.rb +81 -0
- data/lib/milkode/cdweb/lib/search_contents.rb +117 -0
- data/lib/milkode/cdweb/lib/search_files.rb +88 -0
- data/lib/milkode/cdweb/public/css/coderay.css +131 -0
- data/lib/milkode/cdweb/public/css/gren.css +75 -0
- data/lib/milkode/cdweb/public/images/directory.png +0 -0
- data/lib/milkode/cdweb/public/images/file.png +0 -0
- data/lib/milkode/cdweb/public/images/gren-icon-mini.png +0 -0
- data/lib/milkode/cdweb/public/images/gren-icon.png +0 -0
- data/lib/milkode/cdweb/views/filelist.haml +14 -0
- data/lib/milkode/cdweb/views/help.haml +16 -0
- data/lib/milkode/cdweb/views/index.haml +17 -0
- data/lib/milkode/cdweb/views/layout.haml +33 -0
- data/lib/milkode/cdweb/views/search.haml +12 -0
- data/lib/milkode/cdweb/views/view.haml +16 -0
- data/lib/milkode/common/dbdir.rb +39 -0
- data/lib/milkode/common/display_util.rb +62 -0
- data/lib/milkode/common/grenfiletest.rb +19 -0
- data/lib/milkode/common/grensnip.rb +37 -0
- data/lib/milkode/common/platform.rb +17 -0
- data/lib/milkode/common/string_snip.rb +61 -0
- data/lib/milkode/common/util.rb +144 -0
- data/lib/milkode/findgrep/findgrep.rb +408 -0
- data/lib/milkode/findgrep/result.rb +43 -0
- data/milkode.gemspec +159 -0
- data/test/data/abc.zip +0 -0
- data/test/data/nodir_abc.zip +0 -0
- data/test/data/nodir_abc_xpi.xpi +0 -0
- data/test/file_assert.rb +41 -0
- data/test/file_test_utils.rb +59 -0
- data/test/rake_test_loader.rb +7 -0
- data/test/runner.rb +11 -0
- data/test/test_bin_exec.rb +30 -0
- data/test/test_cdstk.rb +90 -0
- data/test/test_cdstk_yaml.rb +157 -0
- data/test/test_coderay_wrapper.rb +22 -0
- data/test/test_coderay_wrapper_data.rb +91 -0
- data/test/test_database.rb +78 -0
- data/test/test_dbdir.rb +60 -0
- data/test/test_gren_util.rb +34 -0
- data/test/test_helper.rb +2 -0
- data/test/test_mkurl.rb +30 -0
- data/test/test_query.rb +54 -0
- data/test/test_string_snip.rb +31 -0
- data/test/test_util.rb +40 -0
- metadata +300 -0
@@ -0,0 +1,111 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'rubygems'
|
3
|
+
require 'rack'
|
4
|
+
require 'launchy'
|
5
|
+
require 'optparse'
|
6
|
+
require 'milkode/cdweb/lib/database'
|
7
|
+
|
8
|
+
module Rack
|
9
|
+
class Server
|
10
|
+
def start
|
11
|
+
if options[:warn]
|
12
|
+
$-w = true
|
13
|
+
end
|
14
|
+
|
15
|
+
if includes = options[:include]
|
16
|
+
$LOAD_PATH.unshift(*includes)
|
17
|
+
end
|
18
|
+
|
19
|
+
if library = options[:require]
|
20
|
+
require library
|
21
|
+
end
|
22
|
+
|
23
|
+
if options[:debug]
|
24
|
+
$DEBUG = true
|
25
|
+
require 'pp'
|
26
|
+
p options[:server]
|
27
|
+
pp wrapped_app
|
28
|
+
pp app
|
29
|
+
end
|
30
|
+
|
31
|
+
# Touch the wrapped app, so that the config.ru is loaded before
|
32
|
+
# daemonization (i.e. before chdir, etc).
|
33
|
+
wrapped_app
|
34
|
+
|
35
|
+
daemonize_app if options[:daemonize]
|
36
|
+
write_pid if options[:pid]
|
37
|
+
|
38
|
+
trap(:INT) do
|
39
|
+
if server.respond_to?(:shutdown)
|
40
|
+
server.shutdown
|
41
|
+
else
|
42
|
+
exit
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
server.run wrapped_app, options do
|
47
|
+
if (options[:LaunchBrowser])
|
48
|
+
host = options[:Host] || options[:BindAddress] # options[:BindAddress] for WEBrick
|
49
|
+
Launchy.open("http://#{host}:#{options[:Port]}")
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
module Milkode
|
57
|
+
class CLI_Cdweb
|
58
|
+
def self.execute(stdout, argv)
|
59
|
+
options = {
|
60
|
+
:environment => ENV['RACK_ENV'] || "development",
|
61
|
+
:pid => nil,
|
62
|
+
:Port => 9292,
|
63
|
+
:Host => "0.0.0.0",
|
64
|
+
:AccessLog => [],
|
65
|
+
:config => "config.ru",
|
66
|
+
# ----------------------------
|
67
|
+
:server => "thin",
|
68
|
+
:LaunchBrowser => true,
|
69
|
+
:DbDir => select_dbdir,
|
70
|
+
}
|
71
|
+
|
72
|
+
opts = OptionParser.new("#{File.basename($0)}")
|
73
|
+
opts.on('--db DB_DIR', 'Database dir (default : current_dir)') {|v| options[:DbDir] = v }
|
74
|
+
opts.on("-o", "--host HOST", "listen on HOST (default: 0.0.0.0)") {|host| options[:Host] = host }
|
75
|
+
opts.on('-p', '--port PORT', 'use PORT (default: 9292)') {|v| options[:Port] = v }
|
76
|
+
opts.on("-s", "--server SERVER", "serve using SERVER (default : thin)") {|s| options[:server] = s }
|
77
|
+
opts.on('-n', '--no-browser', 'No launch browser.') {|v| options[:LaunchBrowser] = false }
|
78
|
+
|
79
|
+
# --hostが'-h'を上書きするので、'-h'を再定義してあげる
|
80
|
+
opts.on_tail("-h", "-?", "--help", "Show this message") do
|
81
|
+
puts opts
|
82
|
+
exit
|
83
|
+
end
|
84
|
+
|
85
|
+
opts.parse!(argv)
|
86
|
+
|
87
|
+
# 実行!!
|
88
|
+
execute_with_options(options)
|
89
|
+
end
|
90
|
+
|
91
|
+
def self.execute_with_options(stdout, options)
|
92
|
+
# 使用するデータベースの位置設定
|
93
|
+
Database.setup(File.expand_path(options[:DbDir]))
|
94
|
+
|
95
|
+
# サーバースクリプトのある場所へ移動
|
96
|
+
FileUtils.cd(File.dirname(__FILE__))
|
97
|
+
|
98
|
+
# Rackサーバー起動
|
99
|
+
Rack::Server.start(options)
|
100
|
+
end
|
101
|
+
|
102
|
+
|
103
|
+
def self.select_dbdir
|
104
|
+
if (Dbdir.dbdir?('.') || !Dbdir.dbdir?(Dbdir.default_dir))
|
105
|
+
'.'
|
106
|
+
else
|
107
|
+
Dbdir.default_dir
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
#
|
3
|
+
# @file
|
4
|
+
# @brief
|
5
|
+
# @author ongaeshi
|
6
|
+
# @date 2011/07/03
|
7
|
+
|
8
|
+
require 'rubygems'
|
9
|
+
require 'coderay'
|
10
|
+
require 'coderay/helpers/file_type'
|
11
|
+
|
12
|
+
module Milkode
|
13
|
+
class CodeRayWrapper
|
14
|
+
attr_reader :line_number_start
|
15
|
+
|
16
|
+
def initialize(content, filename, match_lines = [])
|
17
|
+
@content = content
|
18
|
+
@filename = filename
|
19
|
+
@match_lines = match_lines
|
20
|
+
@highlight_lines = match_lines.map{|v|v.index+1}
|
21
|
+
@line_number_start = 1
|
22
|
+
end
|
23
|
+
|
24
|
+
def set_range(range)
|
25
|
+
content_a = @content.to_a
|
26
|
+
range = limit_range(range, content_a)
|
27
|
+
@content = content_a[range]
|
28
|
+
@line_number_start = range.first + 1
|
29
|
+
end
|
30
|
+
|
31
|
+
def limit_range(range, array)
|
32
|
+
Range.new(range.first < 0 ? 0 : range.first,
|
33
|
+
range.last >= array.size ? array.size - 1 : range.last)
|
34
|
+
end
|
35
|
+
|
36
|
+
def to_html
|
37
|
+
html = CodeRay.scan(@content, file_type).
|
38
|
+
html(
|
39
|
+
:wrap => nil,
|
40
|
+
:line_numbers => :table,
|
41
|
+
:css => :class,
|
42
|
+
:highlight_lines => @highlight_lines,
|
43
|
+
:line_number_start => @line_number_start
|
44
|
+
)
|
45
|
+
|
46
|
+
milkode_ornament(html)
|
47
|
+
end
|
48
|
+
|
49
|
+
def milkode_ornament(html)
|
50
|
+
a = html.split("\n")
|
51
|
+
|
52
|
+
line_number = @line_number_start
|
53
|
+
is_code_content = false
|
54
|
+
|
55
|
+
a.each_with_index do |l, index|
|
56
|
+
if (l =~ / <td class="code"><pre (.*?)>(.*)<tt>/)
|
57
|
+
a[index] = " <td class=\"code\"><pre #{$1}><span #{line_attr(line_number)}>#{$2}</span><tt>"
|
58
|
+
is_code_content = true
|
59
|
+
line_number += 1
|
60
|
+
next
|
61
|
+
elsif (l =~ %r|</tt></pre></td>|)
|
62
|
+
is_code_content = false
|
63
|
+
end
|
64
|
+
|
65
|
+
if (is_code_content)
|
66
|
+
if (l =~ %r|</tt>(.*)<tt>|)
|
67
|
+
a[index] = "</tt><span #{line_attr(line_number)}>#{$1}</span><tt>"
|
68
|
+
line_number += 1
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
a.join("\n") + "\n"
|
74
|
+
end
|
75
|
+
|
76
|
+
def file_type
|
77
|
+
case File.extname(@filename)
|
78
|
+
when ".el"
|
79
|
+
:scheme
|
80
|
+
else
|
81
|
+
CodeRay::FileType.fetch @filename, :plaintext
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def line_attr(no)
|
86
|
+
r = []
|
87
|
+
r << "id=\"#{no}\""
|
88
|
+
r << "class=\"highlight-line\"" if @highlight_lines.include?(no)
|
89
|
+
r.join(" ")
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
#
|
3
|
+
# @file
|
4
|
+
# @brief
|
5
|
+
# @author ongaeshi
|
6
|
+
# @date 2011/07/11
|
7
|
+
|
8
|
+
require 'milkode/cdweb/lib/database'
|
9
|
+
require 'milkode/cdweb/lib/coderay_wrapper'
|
10
|
+
require 'milkode/cdweb/lib/search_contents'
|
11
|
+
require 'milkode/cdweb/lib/search_files'
|
12
|
+
require 'milkode/cdweb/lib/mkurl'
|
13
|
+
|
14
|
+
module Milkode
|
15
|
+
def view(record, params, before)
|
16
|
+
@title = record.shortpath
|
17
|
+
@path = record.shortpath
|
18
|
+
|
19
|
+
q = params[:query] && Query.new(params[:query])
|
20
|
+
|
21
|
+
if (q and !q.keywords.empty?)
|
22
|
+
grep = Grep.new(record.content)
|
23
|
+
match_lines = grep.match_lines_and(q.keywords)
|
24
|
+
@record_content = CodeRayWrapper.new(record.content, record.shortpath, match_lines).to_html
|
25
|
+
else
|
26
|
+
@record_content = CodeRayWrapper.new(record.content, record.shortpath).to_html
|
27
|
+
end
|
28
|
+
|
29
|
+
@elapsed = Time.now - before
|
30
|
+
haml :view
|
31
|
+
end
|
32
|
+
|
33
|
+
def search(path, params, before)
|
34
|
+
@path = path
|
35
|
+
query = Query.new(params[:query])
|
36
|
+
@title = "'#{query.query_string}' in #{path_title(path)}"
|
37
|
+
|
38
|
+
if (query.keywords.size > 0)
|
39
|
+
searcher = SearchContents.new(path, params, query)
|
40
|
+
else
|
41
|
+
searcher = SearchFiles.new(path, params, query)
|
42
|
+
end
|
43
|
+
|
44
|
+
@total_records = searcher.total_records
|
45
|
+
@range = searcher.data_range
|
46
|
+
@record_content = searcher.html_contents + searcher.html_pagination;
|
47
|
+
@elapsed = Time.now - before
|
48
|
+
haml :search
|
49
|
+
end
|
50
|
+
|
51
|
+
def filelist(path, params, before)
|
52
|
+
@title = filelist_title(path)
|
53
|
+
@path = path
|
54
|
+
fileList = Database.instance.fileList(path)
|
55
|
+
@total_records = fileList.size
|
56
|
+
@record_content = fileList.map do |v|
|
57
|
+
"<dt class='result-file'>#{file_or_dirimg(v[1])}<a href='#{Mkurl.new('/home/' + v[0], params).inherit_query_shead}'>#{File.basename v[0]}</a></dt>"
|
58
|
+
end
|
59
|
+
@elapsed = Time.now - before
|
60
|
+
haml :filelist
|
61
|
+
end
|
62
|
+
|
63
|
+
def file_or_dirimg(is_file)
|
64
|
+
src = (is_file) ? '/images/file.png' : '/images/directory.png'
|
65
|
+
"<img alt='' style='vertical-align:bottom; border: 0; margin: 1px;' src='#{src}'>"
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,260 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
#
|
3
|
+
# @file
|
4
|
+
# @brief Milkodeで使用するデータベース
|
5
|
+
# @author ongaeshi
|
6
|
+
# @date 2010/10/17
|
7
|
+
|
8
|
+
require 'rubygems'
|
9
|
+
require 'pathname'
|
10
|
+
require 'singleton'
|
11
|
+
require 'groonga'
|
12
|
+
require 'milkode/common/dbdir'
|
13
|
+
include Milkode
|
14
|
+
|
15
|
+
module Milkode
|
16
|
+
class Database
|
17
|
+
include Singleton
|
18
|
+
|
19
|
+
@@db_dir = nil
|
20
|
+
|
21
|
+
def self.setup(db_dir)
|
22
|
+
@@db_dir = db_dir
|
23
|
+
end
|
24
|
+
|
25
|
+
def initialize
|
26
|
+
open(@@db_dir || Dbdir.default_dir)
|
27
|
+
end
|
28
|
+
|
29
|
+
def open(db_dir)
|
30
|
+
dbfile = Dbdir.expand_groonga_path(db_dir)
|
31
|
+
|
32
|
+
if File.exist? dbfile
|
33
|
+
Groonga::Database.open(dbfile)
|
34
|
+
else
|
35
|
+
raise "error : #{dbfile} not found!!"
|
36
|
+
end
|
37
|
+
|
38
|
+
@documents = Groonga::Context.default["documents"]
|
39
|
+
end
|
40
|
+
|
41
|
+
def record(shortpath)
|
42
|
+
table = @documents.select { |record| record.shortpath == shortpath }
|
43
|
+
return table.records[0]
|
44
|
+
end
|
45
|
+
|
46
|
+
def fileNum
|
47
|
+
@documents.select.size
|
48
|
+
end
|
49
|
+
|
50
|
+
def search(patterns, packages, fpaths, suffixs, offset = 0, limit = -1)
|
51
|
+
# @todo fpathを厳密に検索するには、検索結果からさらに先頭からのパスではないものを除外する
|
52
|
+
records, total_records = searchMain(patterns, packages, fpaths, suffixs, offset, limit)
|
53
|
+
end
|
54
|
+
|
55
|
+
def selectAll(offset = 0, limit = -1)
|
56
|
+
table = @documents.select
|
57
|
+
|
58
|
+
# マッチ数
|
59
|
+
total_records = table.size
|
60
|
+
|
61
|
+
# 2010/10/29 ongaeshi
|
62
|
+
# 本当はこのようにgroongaAPIでソートしたいのだが上手くいかなかった
|
63
|
+
# # ファイル名順にソート
|
64
|
+
# records = table.sort([{:key => "shortpath", :order => "descending"}],
|
65
|
+
# :offset => page * limit,
|
66
|
+
# :limit => limit)
|
67
|
+
|
68
|
+
# ソート
|
69
|
+
if (limit != -1)
|
70
|
+
records = table.records.sort_by{|record| record.shortpath.downcase }[offset, limit]
|
71
|
+
else
|
72
|
+
records = table.records.sort_by{|record| record.shortpath.downcase }[offset..limit]
|
73
|
+
end
|
74
|
+
|
75
|
+
return records, total_records
|
76
|
+
end
|
77
|
+
|
78
|
+
def selectAll2(offset = 0, limit = -1)
|
79
|
+
records, total_records = selectAll(offset, limit)
|
80
|
+
records
|
81
|
+
end
|
82
|
+
|
83
|
+
# レコード数を得る
|
84
|
+
def totalRecords
|
85
|
+
reopen_patch
|
86
|
+
@documents.select.size
|
87
|
+
end
|
88
|
+
|
89
|
+
# @sample test/test_database.rb:43 TestDatabase#t_fileList
|
90
|
+
def fileList(base)
|
91
|
+
base_parts = base.split("/")
|
92
|
+
base_depth = base_parts.length
|
93
|
+
|
94
|
+
# shortpathにマッチするものだけに絞り込む
|
95
|
+
if (base == "")
|
96
|
+
records = @documents.select.records
|
97
|
+
else
|
98
|
+
records = @documents.select {|record| record.shortpath =~ base }.to_a
|
99
|
+
end
|
100
|
+
|
101
|
+
# ファイルリストの生成
|
102
|
+
paths = records.map {|record|
|
103
|
+
record.shortpath.split("/")
|
104
|
+
}.find_all {|parts|
|
105
|
+
parts.length > base_depth and parts[0, base_depth] == base_parts
|
106
|
+
}.map {|parts|
|
107
|
+
is_file = parts.length == base_depth + 1
|
108
|
+
path = parts[0, base_depth + 1].join("/")
|
109
|
+
[path, is_file]
|
110
|
+
}.uniq
|
111
|
+
|
112
|
+
paths
|
113
|
+
end
|
114
|
+
|
115
|
+
# コンテンツの削除
|
116
|
+
# @todo パッケージ名完全一致になっていないので直す
|
117
|
+
def remove(packages)
|
118
|
+
# データベースを開き直す
|
119
|
+
reopen_patch
|
120
|
+
|
121
|
+
# 削除したコンテンツをインデックスから削除
|
122
|
+
records, total_records = search([], packages, [], [])
|
123
|
+
|
124
|
+
# 検索結果はHashのレコードなので、これを直接deleteしても駄目
|
125
|
+
# 1. Record#record_idを使って主キー(Groonga#Arrayのレコード)を取り出し
|
126
|
+
# 2. Record#delete で削除
|
127
|
+
records.each do |r|
|
128
|
+
yield r if block_given?
|
129
|
+
r.record_id.delete
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
# 実体の存在しないデータを削除
|
134
|
+
def cleanup
|
135
|
+
# データベースを開き直す
|
136
|
+
reopen_patch
|
137
|
+
|
138
|
+
# クリーンアップ
|
139
|
+
records = selectAll2
|
140
|
+
|
141
|
+
records.each do |r|
|
142
|
+
unless File.exist? r.path
|
143
|
+
yield r if block_given?
|
144
|
+
r.record_id.delete
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
private
|
150
|
+
|
151
|
+
def reopen_patch
|
152
|
+
# 削除系のコマンドが上手く動作しないためのパッチ
|
153
|
+
# 本質的な解決にはなっていないと思う
|
154
|
+
open(@@db_dir || Dbdir.default_dir)
|
155
|
+
end
|
156
|
+
|
157
|
+
def searchMain(patterns, packages, fpaths, suffixs, offset, limit)
|
158
|
+
table = @documents.select do |record|
|
159
|
+
expression = nil
|
160
|
+
|
161
|
+
# キーワード
|
162
|
+
patterns.each do |word|
|
163
|
+
sub_expression = record.content =~ word
|
164
|
+
if expression.nil?
|
165
|
+
expression = sub_expression
|
166
|
+
else
|
167
|
+
expression &= sub_expression
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
# パッケージ(OR)
|
172
|
+
pe = package_expression(record, packages)
|
173
|
+
if (pe)
|
174
|
+
if expression.nil?
|
175
|
+
expression = pe
|
176
|
+
else
|
177
|
+
expression &= pe
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
# ファイルパス
|
182
|
+
fpaths.each do |word|
|
183
|
+
sub_expression = record.path =~ word
|
184
|
+
if expression.nil?
|
185
|
+
expression = sub_expression
|
186
|
+
else
|
187
|
+
expression &= sub_expression
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
# 拡張子(OR)
|
192
|
+
se = suffix_expression(record, suffixs)
|
193
|
+
if (se)
|
194
|
+
if expression.nil?
|
195
|
+
expression = se
|
196
|
+
else
|
197
|
+
expression &= se
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
# 検索式
|
202
|
+
expression
|
203
|
+
end
|
204
|
+
|
205
|
+
# スコアとタイムスタンプでソート
|
206
|
+
records = table.sort([{:key => "_score", :order => "descending"},
|
207
|
+
{:key => "timestamp", :order => "descending"}],
|
208
|
+
:offset => offset,
|
209
|
+
:limit => limit)
|
210
|
+
|
211
|
+
# パッケージの条件追加
|
212
|
+
if (packages.size > 0)
|
213
|
+
records.delete_if do |record|
|
214
|
+
!packages.any?{|package| record.shortpath.split('/')[0] =~ /#{package}/ }
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
# マッチ数
|
219
|
+
total_records = records.size
|
220
|
+
|
221
|
+
return records, total_records
|
222
|
+
end
|
223
|
+
private :searchMain
|
224
|
+
|
225
|
+
def package_expression(record, packages)
|
226
|
+
sub = nil
|
227
|
+
|
228
|
+
# @todo 専用カラム package が欲しいところ
|
229
|
+
# でも今でもpackageはORとして機能してるからいいっちゃいい
|
230
|
+
packages.each do |word|
|
231
|
+
e = record.path =~ word
|
232
|
+
if sub.nil?
|
233
|
+
sub = e
|
234
|
+
else
|
235
|
+
sub |= e
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
sub
|
240
|
+
end
|
241
|
+
private :package_expression
|
242
|
+
|
243
|
+
def suffix_expression(record, suffixs)
|
244
|
+
sub = nil
|
245
|
+
|
246
|
+
suffixs.each do |word|
|
247
|
+
e = record.suffix =~ word
|
248
|
+
if sub.nil?
|
249
|
+
sub = e
|
250
|
+
else
|
251
|
+
sub |= e
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
sub
|
256
|
+
end
|
257
|
+
private :suffix_expression
|
258
|
+
|
259
|
+
end
|
260
|
+
end
|