Class: FileIndexer::Indexer

Inherits:
Object
  • Object
show all
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

Instance Method Summary collapse

Constructor Details

#initialize(dirs, exts, db_file, &action) ⇒ Indexer

Returns a new instance of Indexer.



24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/file_indexer/indexer.rb', line 24

def initialize(dirs, exts, db_file, &action)
  @dirs    = dirs
  @exts    = exts
  @db_file = db_file
  @action  = action

  @files    = {}
  @listener = nil

  @files.merge!(read_db)
  index_all!
end

Instance Attribute Details

#actionObject

This is a Proc that will be called for every file and its result will be stored in the database



18
19
20
# File 'lib/file_indexer/indexer.rb', line 18

def action
  @action
end

#db_fileObject (readonly)

This is the filename which will be used as the persistent database



22
23
24
# File 'lib/file_indexer/indexer.rb', line 22

def db_file
  @db_file
end

#dirsObject

The directories that will be indexed



12
13
14
# File 'lib/file_indexer/indexer.rb', line 12

def dirs
  @dirs
end

#extsObject

Only files with these extensions will be considered. Just use ‘*’ for all files.



15
16
17
# File 'lib/file_indexer/indexer.rb', line 15

def exts
  @exts
end

#filesObject

This is the actual database of files, it is a Hash



20
21
22
# File 'lib/file_indexer/indexer.rb', line 20

def files
  @files
end

Instance Method Details

#index(files) ⇒ Object

Index a list of files



50
51
52
53
54
# File 'lib/file_indexer/indexer.rb', line 50

def index(files)
  files.map do |file|
    [file, action.(file)]
  end.to_h
end

#index!(nf) ⇒ Object

See Also:



57
58
59
60
61
# File 'lib/file_indexer/indexer.rb', line 57

def index!(nf)
  files.merge!(index(nf))
  changed!
  files
end

#index_all(dirs = @dirs, exts = @exts) ⇒ Object

Index multiple directories



38
39
40
# File 'lib/file_indexer/indexer.rb', line 38

def index_all(dirs = @dirs, exts = @exts)
  dirs.map { |dir| index(glob(dir, exts)) }.reduce(&:merge)
end

#index_all!(dirs = @dirs, exts = @exts) ⇒ Object

See Also:



43
44
45
46
47
# File 'lib/file_indexer/indexer.rb', line 43

def index_all!(dirs = @dirs, exts = @exts)
  @files = index_all(dirs, exts)
  changed!
  files
end

#read_dbObject

Read the database from disk



85
86
87
88
# File 'lib/file_indexer/indexer.rb', line 85

def read_db
  return {} unless File.exist?(db_file)
  File.open(db_file, 'r') { |f| Marshal.load(f.read) }
end

#stopObject

Stop watching directories for changes



75
76
77
# File 'lib/file_indexer/indexer.rb', line 75

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.



65
66
67
68
69
70
71
72
# File 'lib/file_indexer/indexer.rb', line 65

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_dbObject

Write the databse to disk



80
81
82
# File 'lib/file_indexer/indexer.rb', line 80

def write_db
  File.open(db_file, 'w') { |f| f.puts(Marshal.dump(files)) }
end