Class: FileIndexer::Indexer
- Inherits:
-
Object
- Object
- FileIndexer::Indexer
- Includes:
- Observable
- Defined in:
- lib/file_indexer/indexer.rb
Overview
A simple file indexer, keeps a database of files and associated metadata
Instance Attribute Summary collapse
-
#action ⇒ Object
This is a Proc that will be called for every file and its result will be stored in the database.
-
#db_file ⇒ Object
readonly
This is the filename which will be used as the persistent database.
-
#dirs ⇒ Object
The directories that will be indexed.
-
#exts ⇒ Object
Only files with these extensions will be considered.
-
#files ⇒ Object
This is the actual database of files, it is a Hash.
Instance Method Summary collapse
-
#index(fs) ⇒ Object
Index a list of files.
- #index!(fs) ⇒ Object
-
#index_all(dirs = @dirs, exts = @exts) ⇒ Object
Index multiple directories.
- #index_all!(dirs = @dirs, exts = @exts) ⇒ Object
-
#initialize(dirs, exts, db_file, &action) ⇒ Indexer
constructor
A new instance of Indexer.
-
#prune! ⇒ Object
Prune nonexistant files from the index.
-
#read_db ⇒ Object
Read the database from disk.
-
#stop ⇒ Object
Stop watching directories for changes.
-
#watch(dirs = @dirs, exts = @exts) ⇒ Object
Watch directories for changes using the listen gem, when called make sure to call #stop when done watching.
-
#write_db ⇒ Object
Write the databse to disk.
Constructor Details
#initialize(dirs, exts, db_file, &action) ⇒ Indexer
Returns a new instance of Indexer.
25 26 27 28 29 30 31 32 33 34 35 36 37 |
# File 'lib/file_indexer/indexer.rb', line 25 def initialize(dirs, exts, db_file, &action) @dirs = dirs.map { |d| sanitize_dirpath(d) } @exts = exts @db_file = db_file @action = action @files = {} @listener = nil @files.merge!(read_db) prune! index_all! end |
Instance Attribute Details
#action ⇒ Object
This is a Proc that will be called for every file and its result will be stored in the database
19 20 21 |
# File 'lib/file_indexer/indexer.rb', line 19 def action @action end |
#db_file ⇒ Object (readonly)
This is the filename which will be used as the persistent database
23 24 25 |
# File 'lib/file_indexer/indexer.rb', line 23 def db_file @db_file end |
#dirs ⇒ Object
The directories that will be indexed
13 14 15 |
# File 'lib/file_indexer/indexer.rb', line 13 def dirs @dirs end |
#exts ⇒ Object
Only files with these extensions will be considered. Just use ‘*’ for all files.
16 17 18 |
# File 'lib/file_indexer/indexer.rb', line 16 def exts @exts end |
#files ⇒ Object
This is the actual database of files, it is a Hash
21 22 23 |
# File 'lib/file_indexer/indexer.rb', line 21 def files @files end |
Instance Method Details
#index(fs) ⇒ Object
Index a list of files
52 53 54 55 56 57 |
# File 'lib/file_indexer/indexer.rb', line 52 def index(fs) fs.map do |file| next if files.key?(file) [file, action.(file)] end.compact.to_h end |
#index!(fs) ⇒ Object
60 61 62 63 64 |
# File 'lib/file_indexer/indexer.rb', line 60 def index!(fs) files.merge!(index(fs)) changed! files end |
#index_all(dirs = @dirs, exts = @exts) ⇒ Object
Index multiple directories
40 41 42 |
# File 'lib/file_indexer/indexer.rb', line 40 def index_all(dirs = @dirs, exts = @exts) dirs.map { |dir| index(glob(dir, exts)) }.reduce(&:merge) end |
#index_all!(dirs = @dirs, exts = @exts) ⇒ Object
45 46 47 48 49 |
# File 'lib/file_indexer/indexer.rb', line 45 def index_all!(dirs = @dirs, exts = @exts) files.merge!(index_all(dirs, exts)) changed! files end |
#prune! ⇒ Object
Prune nonexistant files from the index
67 68 69 |
# File 'lib/file_indexer/indexer.rb', line 67 def prune! files.select! { |f,_| File.exist?(f) }.to_h end |
#read_db ⇒ Object
Read the database from disk
93 94 95 96 |
# File 'lib/file_indexer/indexer.rb', line 93 def read_db return {} unless File.exist?(db_file) File.open(db_file, 'r') { |f| Marshal.load(f.read) } end |
#stop ⇒ Object
Stop watching directories for changes
83 84 85 |
# File 'lib/file_indexer/indexer.rb', line 83 def stop @listener&.stop end |
#watch(dirs = @dirs, exts = @exts) ⇒ Object
Watch directories for changes using the listen gem, when called make sure to call #stop when done watching.
73 74 75 76 77 78 79 80 |
# File 'lib/file_indexer/indexer.rb', line 73 def watch(dirs = @dirs, exts = @exts) @listener = Listen.to(*dirs, only: /\.(#{exts.join('|')})$/) do |mod, add, del| del.each { |f| files.delete(f) } index!(mod + add) end @listener.start end |
#write_db ⇒ Object
Write the databse to disk
88 89 90 |
# File 'lib/file_indexer/indexer.rb', line 88 def write_db File.open(db_file, 'w') { |f| f.puts(Marshal.dump(files)) } end |