/
source.rb
79 lines (68 loc) · 2.41 KB
/
source.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
class Source
include Tire::Model::Persistence
property :apk_eid
property :path
property :lib
property :core
property :lines
property :num_lines
property :size
tire.mapping :_all => {:enabled => false} do
indexes :apk_eid, :index => :not_analyzed, :store => :yes
indexes :path, :index => :not_analyzed, :store => :yes
indexes :lib, :index => :not_analyzed, :store => :yes
indexes :core, :type => :boolean, :store => :yes
indexes :lines, :analyzer => :simple
indexes :num_lines, :type => :integer, :store => :yes
indexes :size, :type => :integer, :store => :yes
end
def self.index_sources!(apk)
base_len = nil
lib_re = Lib.lib_re
core_re = Regexp.new("^#{apk.package_name.gsub('.', '/')}/")
sources = []
apk.source_dir.find do |f|
base_len = f.to_s.size if base_len.nil?
if f.file? && f.extname == '.java'
lines = f.open.lines.map(&:chomp)
path = f.to_s[base_len+1..-1]
attrs = { :id => Moped::BSON::ObjectId.new.to_s,
:apk_eid => apk.eid,
:path => path,
:lines => lines,
:num_lines => lines.count,
:size => f.size}
attrs[:lib] = $1.gsub('/', '.') if path =~ lib_re
attrs[:core] = true if path =~ core_re
sources << new(attrs)
end
end
index.import sources
true
end
def self.purge_index!(apk)
Tire::Configuration.client.delete "#{index.url}/_query?q=apk_eid:#{apk.eid}"
end
def self.search(query, options={})
tire.search(options) do
query { string query, :default_field => :lines, :default_operator => 'AND' }
highlight :lines => {:fragment_size => 300, :number_of_fragments => 100000}, :options => {:tag => ''}
fields :apk_eid, :path
facet(:num_lines) { statistical :num_lines }
facet(:size) { statistical :size }
end
end
def self.filter_lines(results, regex=nil)
per_file_lines = []
results.each do |source|
next unless source.highlight
matched_lines = source.highlight[:lines]
matched_lines = matched_lines.grep(regex) if regex
next if matched_lines.empty?
per_file_lines << {:apk_eid => source.apk_eid,
:path => source.path,
:lines => matched_lines}
end
per_file_lines
end
end