milkode 0.1.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/.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
|