xapian-findex 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.
- checksums.yaml +7 -0
- data/.gitignore +11 -0
- data/.rspec +2 -0
- data/.travis.yml +4 -0
- data/Gemfile +4 -0
- data/README.md +84 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/exe/findex +5 -0
- data/lib/findex/cli.rb +31 -0
- data/lib/findex/config.rb +12 -0
- data/lib/findex/document_decorator.rb +119 -0
- data/lib/findex/dsl.rb +21 -0
- data/lib/findex/file_indexer.rb +20 -0
- data/lib/findex/index.rb +25 -0
- data/lib/findex/indexer.rb +88 -0
- data/lib/findex/search.rb +51 -0
- data/lib/findex/term_generator_decorator.rb +18 -0
- data/lib/findex/version.rb +3 -0
- data/lib/findex.rb +4 -0
- data/xapian-findex.gemspec +31 -0
- metadata +166 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: ad6429b138298d9caddc9f7db8be15022c1ea77f
|
4
|
+
data.tar.gz: 71a45fe807933edefeabfdb0c97e66af6ac4965d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 6bc6c9b451c6c10fd3d20b83db5a0385fa1f9f8d2774a93f7d6c058442e85c69e096eec882da17ba57d0b7f99a9cef0d0c4cb9028b9d5a8152b78c1d7940e7a7
|
7
|
+
data.tar.gz: e63c6474704a29b0f6de957ff0eadccc490224b36197a2b60bf0e8c156083244c3e0b13b74783c74c1c7ecfc9cac5ffa178bfa3b953783dbf91835a68649c213
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
# Findex
|
2
|
+
|
3
|
+
Findex is a command line file indexing tool. It performs full text indexing
|
4
|
+
with [Xapian](http://xapian.org) as Backend and allows a great deal of
|
5
|
+
customization via a simple DSL.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
$ gem install xapian-findex
|
10
|
+
|
11
|
+
### Dependencies
|
12
|
+
|
13
|
+
- xapian-core
|
14
|
+
- libmagic
|
15
|
+
|
16
|
+
## Usage
|
17
|
+
|
18
|
+
### Indexing
|
19
|
+
|
20
|
+
$ findex index [path]
|
21
|
+
|
22
|
+
### Searching
|
23
|
+
|
24
|
+
$ findex search [path] -- some xapian search query
|
25
|
+
|
26
|
+
The following prefixes are available by default:
|
27
|
+
|
28
|
+
- `date` - the mtime of the document (allows [value range queries](http://xapian.org/docs/valueranges.html)
|
29
|
+
- `path` - the relative path of the file
|
30
|
+
|
31
|
+
## DSL
|
32
|
+
|
33
|
+
Findex will add a directory `.findex` in the indexed path. This directory
|
34
|
+
contains the database and a `config.rb` file. This way you can move your
|
35
|
+
indexed directory to another location without affecting the index. This also
|
36
|
+
simplifies backups.
|
37
|
+
|
38
|
+
You can customize the behavior of the index by editing `config.rb`.
|
39
|
+
|
40
|
+
### Options
|
41
|
+
|
42
|
+
Below are the available options for Findex with their defaults. It should give
|
43
|
+
you an idea how to change them to fit your needs.
|
44
|
+
|
45
|
+
``` ruby
|
46
|
+
indexer.stem_language = 'none'
|
47
|
+
```
|
48
|
+
|
49
|
+
### Mimetypes
|
50
|
+
|
51
|
+
Findex uses libmagic to determine the mimetypes of files to be indexed. To
|
52
|
+
configure special handling for pdf files you could add the following to your
|
53
|
+
`config.rb`:
|
54
|
+
|
55
|
+
``` ruby
|
56
|
+
indexer.on('application/pdf') do |file, index|
|
57
|
+
metadata = `pdfinfo "#{file}"`.lines.map { |l| l.chomp.split(/:\s+/) }.to_h
|
58
|
+
index[:title] = metadata["Title"]
|
59
|
+
index[:author] = metadata["Author"]
|
60
|
+
index << `pdf2text "#{file}" -`
|
61
|
+
end
|
62
|
+
```
|
63
|
+
|
64
|
+
An example search query:
|
65
|
+
|
66
|
+
$ findex search path/to/my/library -- author:'Jules Verne'
|
67
|
+
|
68
|
+
## Development
|
69
|
+
|
70
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run
|
71
|
+
`rake spec` to run the tests. You can also run `bin/console` for an interactive
|
72
|
+
prompt that will allow you to experiment.
|
73
|
+
|
74
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To
|
75
|
+
release a new version, update the version number in `version.rb`, and then run
|
76
|
+
`bundle exec rake release`, which will create a git tag for the version, push
|
77
|
+
git commits and tags, and push the `.gem` file to
|
78
|
+
[rubygems.org](https://rubygems.org).
|
79
|
+
|
80
|
+
## Contributing
|
81
|
+
|
82
|
+
Bug reports and pull requests are welcome on GitHub at
|
83
|
+
https://github.com/jreinert/findex.
|
84
|
+
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "findex"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start
|
data/bin/setup
ADDED
data/exe/findex
ADDED
data/lib/findex/cli.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require_relative './indexer'
|
2
|
+
require_relative './search'
|
3
|
+
|
4
|
+
module Findex
|
5
|
+
class Cli
|
6
|
+
USAGE = "Usage: #{$PROGRAM_NAME} (index|search) [path] [-- query]".freeze
|
7
|
+
|
8
|
+
def initialize(args)
|
9
|
+
query_separator_index = args.find_index('--') || -1
|
10
|
+
action, path = args[0..query_separator_index]
|
11
|
+
|
12
|
+
case action
|
13
|
+
when 'index' then index(path || '.')
|
14
|
+
when 'search'
|
15
|
+
abort(USAGE) if query_separator_index == -1
|
16
|
+
search(path, args[query_separator_index..-1])
|
17
|
+
else abort("Unsupported action '#{action}'\n#{USAGE}")
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def index(path)
|
22
|
+
Indexer.new(path || '.').start
|
23
|
+
end
|
24
|
+
|
25
|
+
def search(path, query_terms)
|
26
|
+
Search.new(path || '.').query(query_terms).each do |document|
|
27
|
+
puts document.full_path
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
require 'time'
|
2
|
+
require 'date'
|
3
|
+
require 'xapian'
|
4
|
+
require_relative './file_indexer'
|
5
|
+
require_relative './term_generator_decorator'
|
6
|
+
|
7
|
+
module Findex
|
8
|
+
# A decorator class to be used around Xapian::Documents
|
9
|
+
class DocumentDecorator < SimpleDelegator
|
10
|
+
TIME_FORMAT = '%s'.freeze
|
11
|
+
DATE_FORMAT = '%Y%m%d'.freeze
|
12
|
+
VALUE_SLOTS = {
|
13
|
+
path: 0,
|
14
|
+
mtime: 1,
|
15
|
+
date: 2
|
16
|
+
}.freeze
|
17
|
+
|
18
|
+
attr_reader :xapian_document
|
19
|
+
|
20
|
+
def initialize(xapian_document, root_path, file = nil)
|
21
|
+
@xapian_document = xapian_document
|
22
|
+
@root_path = root_path
|
23
|
+
super(xapian_document)
|
24
|
+
update_values_from(file) if file
|
25
|
+
end
|
26
|
+
|
27
|
+
def path
|
28
|
+
@path ||= value(:path)
|
29
|
+
end
|
30
|
+
|
31
|
+
def path=(path)
|
32
|
+
add_value(:path, path.to_s)
|
33
|
+
@path = path
|
34
|
+
end
|
35
|
+
|
36
|
+
def mtime
|
37
|
+
@mtime ||= Time.strptime(value(:mtime), TIME_FORMAT)
|
38
|
+
end
|
39
|
+
|
40
|
+
def actual_mtime
|
41
|
+
Time.at(full_path.mtime.to_i)
|
42
|
+
end
|
43
|
+
|
44
|
+
def mtime=(time)
|
45
|
+
add_value(:mtime, time.strftime(TIME_FORMAT))
|
46
|
+
@mtime = time
|
47
|
+
end
|
48
|
+
|
49
|
+
def date
|
50
|
+
@date ||= Date.strptime(value(:date), DATE_FORMAT)
|
51
|
+
end
|
52
|
+
|
53
|
+
def date=(date)
|
54
|
+
add_value(:date, date.strftime(DATE_FORMAT))
|
55
|
+
@date = date
|
56
|
+
end
|
57
|
+
|
58
|
+
def exists?
|
59
|
+
full_path.exist?
|
60
|
+
end
|
61
|
+
|
62
|
+
def deleted?
|
63
|
+
!exists?
|
64
|
+
end
|
65
|
+
|
66
|
+
def changed?
|
67
|
+
actual_mtime > mtime
|
68
|
+
end
|
69
|
+
|
70
|
+
def extension
|
71
|
+
path.extname[1..-1]
|
72
|
+
end
|
73
|
+
|
74
|
+
def value(slot)
|
75
|
+
return super if slot.is_a?(Integer)
|
76
|
+
super(VALUE_SLOTS[slot])
|
77
|
+
end
|
78
|
+
|
79
|
+
def add_value(slot, value)
|
80
|
+
return super if slot.is_a?(Integer)
|
81
|
+
super(VALUE_SLOTS[slot], value)
|
82
|
+
end
|
83
|
+
|
84
|
+
def update(db, term_generator)
|
85
|
+
index(term_generator)
|
86
|
+
db.replace_document(docid, xapian_document)
|
87
|
+
end
|
88
|
+
|
89
|
+
def insert(db, term_generator)
|
90
|
+
index(term_generator)
|
91
|
+
db.add_document(xapian_document)
|
92
|
+
end
|
93
|
+
|
94
|
+
def full_path
|
95
|
+
@root_path + path
|
96
|
+
end
|
97
|
+
|
98
|
+
private
|
99
|
+
|
100
|
+
def index(term_generator)
|
101
|
+
update_values_from(full_path)
|
102
|
+
clear_terms
|
103
|
+
term_generator.document = xapian_document
|
104
|
+
index_text(TermGeneratorDecorator.new(term_generator))
|
105
|
+
end
|
106
|
+
|
107
|
+
def index_text(term_generator)
|
108
|
+
file_indexer = FileIndexer.new(full_path)
|
109
|
+
term_generator[:path] = path
|
110
|
+
file_indexer.index(term_generator)
|
111
|
+
end
|
112
|
+
|
113
|
+
def update_values_from(file)
|
114
|
+
self.path = file.relative_path_from(@root_path)
|
115
|
+
self.mtime = full_path.mtime
|
116
|
+
self.date = mtime.to_date
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
data/lib/findex/dsl.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require_relative './config'
|
2
|
+
|
3
|
+
module Findex
|
4
|
+
class DSL
|
5
|
+
attr_reader :definitions
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@definitions = {}
|
9
|
+
@config = Config.new
|
10
|
+
end
|
11
|
+
|
12
|
+
def on(extension, &block)
|
13
|
+
@definitions[extension] = block
|
14
|
+
end
|
15
|
+
|
16
|
+
def config(&block)
|
17
|
+
return @config unless block_given?
|
18
|
+
@config = Config.new(&block)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require_relative './index'
|
2
|
+
require 'filemagic'
|
3
|
+
|
4
|
+
module Findex
|
5
|
+
class FileIndexer
|
6
|
+
TEXT_INDEXER = lambda do |file, index|
|
7
|
+
index << File.read(file)
|
8
|
+
end
|
9
|
+
|
10
|
+
def initialize(file)
|
11
|
+
@file = file
|
12
|
+
@mime = FileMagic.open(:mime_type) { |magic| magic.file(file.to_s) }
|
13
|
+
end
|
14
|
+
|
15
|
+
def index(term_generator)
|
16
|
+
indexer = Findex.definitions[@mime] || TEXT_INDEXER
|
17
|
+
indexer.call(@file, term_generator)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/lib/findex/index.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'logger'
|
2
|
+
require_relative './dsl'
|
3
|
+
|
4
|
+
module Findex
|
5
|
+
def self.index
|
6
|
+
dsl = DSL.new
|
7
|
+
yield dsl
|
8
|
+
@definitions = dsl.definitions
|
9
|
+
@config = dsl.config
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.definitions
|
13
|
+
@definitions
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.config
|
17
|
+
@config
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.logger
|
21
|
+
@logger ||= Logger.new(STDOUT).tap do |logger|
|
22
|
+
logger.level = config.log_level
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
require 'xapian'
|
2
|
+
require 'pathname'
|
3
|
+
require_relative './document_decorator'
|
4
|
+
require_relative './config'
|
5
|
+
|
6
|
+
module Findex
|
7
|
+
# Class used for indexing files
|
8
|
+
class Indexer
|
9
|
+
DB_FLAGS = Xapian::DB_CREATE_OR_OPEN
|
10
|
+
|
11
|
+
def initialize(root_path)
|
12
|
+
@root_path = Pathname.new(root_path)
|
13
|
+
@findex_path = @root_path + '.findex'
|
14
|
+
setup
|
15
|
+
end
|
16
|
+
|
17
|
+
def start
|
18
|
+
@db.begin_transaction
|
19
|
+
existing = refresh_existing
|
20
|
+
files.each do |file|
|
21
|
+
next if existing.include?(file)
|
22
|
+
insert(file)
|
23
|
+
end
|
24
|
+
@db.commit_transaction
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def insert(file)
|
30
|
+
xapian_document = Xapian::Document.new
|
31
|
+
document = DocumentDecorator.new(xapian_document, @root_path, file)
|
32
|
+
Findex.logger.info("adding '#{document.path}' to the index")
|
33
|
+
document.insert(@db, @term_generator)
|
34
|
+
end
|
35
|
+
|
36
|
+
def files
|
37
|
+
Enumerator.new do |y|
|
38
|
+
Pathname.glob(@root_path + '**' + '*').each do |path|
|
39
|
+
next if path.ascend.any? { |p| p == @findex_path }
|
40
|
+
next if path.directory?
|
41
|
+
y << Pathname.new(path)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def refresh_existing
|
47
|
+
documents.map do |document|
|
48
|
+
if document.deleted?
|
49
|
+
Findex.logger.info("deleting '#{document.path}' from index")
|
50
|
+
@db.delete_document(document.docid)
|
51
|
+
elsif document.changed?
|
52
|
+
Findex.logger.info("updating '#{document.path}'")
|
53
|
+
document.update(@db, @term_generator)
|
54
|
+
end
|
55
|
+
|
56
|
+
document.full_path
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def documents
|
61
|
+
enquire = Xapian::Enquire.new(@db)
|
62
|
+
enquire.query = Xapian::Query::MatchAll
|
63
|
+
mset = enquire.mset(0, @db.doccount)
|
64
|
+
Enumerator.new do |y|
|
65
|
+
mset.matches.each do |match|
|
66
|
+
y << DocumentDecorator.new(match.document, @root_path)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def setup
|
72
|
+
unless @findex_path.exist?
|
73
|
+
@findex_path.mkdir
|
74
|
+
File.write(@findex_path + 'config.rb', "Findex.index do |indexer|\nend")
|
75
|
+
end
|
76
|
+
|
77
|
+
require((@findex_path + 'config.rb').realpath)
|
78
|
+
setup_db
|
79
|
+
end
|
80
|
+
|
81
|
+
def setup_db
|
82
|
+
@db = Xapian::WritableDatabase.new((@findex_path + 'db').to_s, DB_FLAGS)
|
83
|
+
@term_generator = Xapian::TermGenerator.new
|
84
|
+
@term_generator.database = @db
|
85
|
+
@term_generator.stemmer = Xapian::Stem.new(Findex.config.stem_language)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Findex
|
2
|
+
class Search
|
3
|
+
def initialize(root_path)
|
4
|
+
@root_path = Pathname.new(root_path)
|
5
|
+
@findex_path = @root_path + '.findex'
|
6
|
+
setup
|
7
|
+
end
|
8
|
+
|
9
|
+
def query(query_terms)
|
10
|
+
enquire = Xapian::Enquire.new(@db)
|
11
|
+
add_prefixes(query_terms)
|
12
|
+
query_terms.map! { |term| term =~ /\s+/ ? %("#{term}") : term }
|
13
|
+
enquire.query = @query_parser.parse_query(query_terms.join(' '))
|
14
|
+
mset = enquire.mset(0, @db.doccount)
|
15
|
+
Enumerator.new do |y|
|
16
|
+
mset.matches.each do |match|
|
17
|
+
document = DocumentDecorator.new(match.document, @root_path)
|
18
|
+
y << document
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def add_prefixes(query_terms)
|
26
|
+
prefix_regex = /(?<prefix>\w+):/
|
27
|
+
query_terms.each do |term|
|
28
|
+
match = term.match(prefix_regex)
|
29
|
+
next unless match
|
30
|
+
prefix = match[:prefix]
|
31
|
+
@query_parser.add_prefix(prefix, "X#{prefix}".upcase)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def setup
|
36
|
+
db_path = @findex_path + 'db'
|
37
|
+
unless @findex_path.exist? && db_path.exist?
|
38
|
+
raise "No index in '#{@root_path}', run index first."
|
39
|
+
end
|
40
|
+
require((@findex_path + 'config.rb').realpath)
|
41
|
+
setup_db(db_path)
|
42
|
+
end
|
43
|
+
|
44
|
+
def setup_db(db_path)
|
45
|
+
@db = Xapian::Database.new(db_path.to_s)
|
46
|
+
@query_parser = Xapian::QueryParser.new
|
47
|
+
@query_parser.stemmer = Xapian::Stem.new(Findex.config.stem_language)
|
48
|
+
@query_parser.database = @db
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Findex
|
2
|
+
class TermGeneratorDecorator < SimpleDelegator
|
3
|
+
def initialize(term_generator)
|
4
|
+
@term_generator = term_generator
|
5
|
+
super
|
6
|
+
end
|
7
|
+
|
8
|
+
def []=(prefix, text)
|
9
|
+
prefix = prefix ? "X#{prefix}".upcase : ''
|
10
|
+
@term_generator.index_text(text.to_s, 1, prefix)
|
11
|
+
@term_generator.increase_termpos
|
12
|
+
end
|
13
|
+
|
14
|
+
def <<(text)
|
15
|
+
self[nil] = text
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/findex.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'findex/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'xapian-findex'
|
8
|
+
spec.version = Findex::VERSION
|
9
|
+
spec.authors = ['Joakim Reinert']
|
10
|
+
spec.email = ['mail@jreinert.com']
|
11
|
+
spec.license = 'MIT'
|
12
|
+
|
13
|
+
spec.summary = 'A simple file indexer and full text search using Xapian'
|
14
|
+
spec.description = 'Findex indexes files in a path recursively, updates ' \
|
15
|
+
'existing ones and deletes removed files from the index'
|
16
|
+
spec.homepage = 'https://github.com/jreinert/findex'
|
17
|
+
|
18
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f =~ %r{^(test|spec|features)/} }
|
19
|
+
spec.bindir = 'exe'
|
20
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
21
|
+
spec.require_paths = ['lib']
|
22
|
+
|
23
|
+
spec.add_dependency 'xapian', '~> 1.2'
|
24
|
+
spec.add_dependency 'ruby-filemagic', '~> 0.7'
|
25
|
+
|
26
|
+
spec.add_development_dependency 'bundler', '~> 1.11'
|
27
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
28
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
29
|
+
spec.add_development_dependency 'pry-byebug', '~> 3.3'
|
30
|
+
spec.add_development_dependency 'pry-doc', '~> 0.8'
|
31
|
+
end
|
metadata
ADDED
@@ -0,0 +1,166 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: xapian-findex
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Joakim Reinert
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-05-15 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: xapian
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.2'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.2'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: ruby-filemagic
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0.7'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0.7'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: bundler
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.11'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.11'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '10.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '10.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '3.0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '3.0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: pry-byebug
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '3.3'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '3.3'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: pry-doc
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0.8'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0.8'
|
111
|
+
description: Findex indexes files in a path recursively, updates existing ones and
|
112
|
+
deletes removed files from the index
|
113
|
+
email:
|
114
|
+
- mail@jreinert.com
|
115
|
+
executables:
|
116
|
+
- findex
|
117
|
+
extensions: []
|
118
|
+
extra_rdoc_files: []
|
119
|
+
files:
|
120
|
+
- ".gitignore"
|
121
|
+
- ".rspec"
|
122
|
+
- ".travis.yml"
|
123
|
+
- Gemfile
|
124
|
+
- README.md
|
125
|
+
- Rakefile
|
126
|
+
- bin/console
|
127
|
+
- bin/setup
|
128
|
+
- exe/findex
|
129
|
+
- lib/findex.rb
|
130
|
+
- lib/findex/cli.rb
|
131
|
+
- lib/findex/config.rb
|
132
|
+
- lib/findex/document_decorator.rb
|
133
|
+
- lib/findex/dsl.rb
|
134
|
+
- lib/findex/file_indexer.rb
|
135
|
+
- lib/findex/index.rb
|
136
|
+
- lib/findex/indexer.rb
|
137
|
+
- lib/findex/search.rb
|
138
|
+
- lib/findex/term_generator_decorator.rb
|
139
|
+
- lib/findex/version.rb
|
140
|
+
- xapian-findex.gemspec
|
141
|
+
homepage: https://github.com/jreinert/findex
|
142
|
+
licenses:
|
143
|
+
- MIT
|
144
|
+
metadata: {}
|
145
|
+
post_install_message:
|
146
|
+
rdoc_options: []
|
147
|
+
require_paths:
|
148
|
+
- lib
|
149
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
150
|
+
requirements:
|
151
|
+
- - ">="
|
152
|
+
- !ruby/object:Gem::Version
|
153
|
+
version: '0'
|
154
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
155
|
+
requirements:
|
156
|
+
- - ">="
|
157
|
+
- !ruby/object:Gem::Version
|
158
|
+
version: '0'
|
159
|
+
requirements: []
|
160
|
+
rubyforge_project:
|
161
|
+
rubygems_version: 2.5.1
|
162
|
+
signing_key:
|
163
|
+
specification_version: 4
|
164
|
+
summary: A simple file indexer and full text search using Xapian
|
165
|
+
test_files: []
|
166
|
+
has_rdoc:
|