fuzzy_notes 0.0.3 → 0.0.5
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/TODO +0 -1
- data/lib/fuzzy_notes/cipher.rb +56 -24
- data/lib/fuzzy_notes/fuzzy_finder.rb +28 -22
- data/lib/fuzzy_notes/notes.rb +87 -79
- metadata +8 -8
data/TODO
CHANGED
data/lib/fuzzy_notes/cipher.rb
CHANGED
@@ -1,37 +1,69 @@
|
|
1
1
|
require 'gibberish'
|
2
2
|
|
3
3
|
class FuzzyNotes::Cipher
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
4
|
+
include FuzzyNotes::Logger
|
5
|
+
|
6
|
+
PLAINTEXT_EXT = 'txt'
|
7
|
+
CIPHERTEXT_EXT = 'enc'
|
8
|
+
|
9
|
+
def encrypt(file_paths, opts = {})
|
10
|
+
@action = :enc
|
11
|
+
apply_cipher(file_paths, opts)
|
12
|
+
end
|
13
|
+
|
14
|
+
def decrypt(file_paths, opts = {})
|
15
|
+
@action = :dec
|
16
|
+
apply_cipher(file_paths, opts)
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def apply_cipher(file_paths, opts)
|
22
|
+
cipher = Gibberish::AES.new(get_password)
|
23
|
+
case file_paths
|
24
|
+
when Array
|
25
|
+
file_paths.each { |path| process_file(path, cipher, opts) }
|
26
|
+
when String
|
27
|
+
process_file(file_paths, cipher, opts)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def process_file(path, cipher, opts)
|
32
|
+
begin
|
33
|
+
log.debug "#{@action} '#{path}'"
|
34
|
+
content = cipher.send(@action, File.read(path))
|
35
|
+
replace_file!(path, content) if opts[:replace]
|
36
|
+
content
|
37
|
+
rescue OpenSSL::Cipher::CipherError => e
|
38
|
+
log.error e
|
26
39
|
end
|
27
40
|
end
|
28
41
|
|
42
|
+
def replace_file!(path, contents)
|
43
|
+
dirname = File.dirname(path)
|
44
|
+
filename = File.basename(path, '.*')
|
45
|
+
|
46
|
+
log.debug "writing #{decrypt? ? 'un' : ''}encrypted content to: #{dirname}/#{filename}.#{extension}"
|
47
|
+
File.open("#{dirname}/#{filename}.#{extension}", 'w') { |f| f << contents }
|
29
48
|
|
30
|
-
|
49
|
+
log.debug "deleting #{decrypt? ? '' : 'un'}encrypted file: #{path}"
|
50
|
+
File.delete(path)
|
51
|
+
end
|
52
|
+
|
53
|
+
def extension
|
54
|
+
decrypt? ? PLAINTEXT_EXT : CIPHERTEXT_EXT
|
55
|
+
end
|
56
|
+
|
57
|
+
def decrypt?
|
58
|
+
@action == :dec
|
59
|
+
end
|
60
|
+
|
61
|
+
def get_password
|
31
62
|
printf 'Enter password (will not be shown):'
|
32
|
-
`stty -echo`; password = STDIN.gets.strip;`stty echo`; puts
|
63
|
+
`stty -echo`; password = STDIN.gets.strip;`stty echo`; puts "\n\n"
|
33
64
|
log.debug "entered password: #{password.inspect}"
|
34
65
|
password
|
35
66
|
end
|
36
67
|
|
68
|
+
|
37
69
|
end
|
@@ -1,45 +1,51 @@
|
|
1
1
|
require 'find'
|
2
2
|
|
3
3
|
class FuzzyNotes::FuzzyFinder
|
4
|
-
|
5
|
-
private_class_method :new
|
4
|
+
include FuzzyNotes::Logger
|
6
5
|
|
6
|
+
attr_reader :path, :all_files, :matching_files, :keywords, :extensions, :full_text_search
|
7
7
|
|
8
|
-
def
|
9
|
-
|
10
|
-
match_proc = method(search ? :full_text_match? : :file_name_match?)
|
8
|
+
def initialize(path, params = {})
|
9
|
+
@path = path
|
11
10
|
log.debug "search path: #{path}"
|
12
11
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
12
|
+
@keywords, @extensions, @search_type = params.values_at(:keywords, :extensions, :full_text_search)
|
13
|
+
self.refresh
|
14
|
+
end
|
15
|
+
|
16
|
+
def refresh
|
17
|
+
clear_results
|
18
|
+
Find.find(*@path) do |file_path|
|
19
|
+
if !File.directory?(file_path) && extension_match?(file_path)
|
20
|
+
@all_files << file_path
|
21
|
+
@matching_files << file_path if file_match_proc.call(file_path)
|
18
22
|
end
|
19
23
|
end
|
20
|
-
|
21
|
-
[all_files.sort, matching_files.sort]
|
22
24
|
end
|
23
25
|
|
24
|
-
|
25
26
|
private
|
26
27
|
|
27
|
-
|
28
|
-
|
29
|
-
file_name = File.basename(file_path)
|
30
|
-
!extensions || extensions.any? {|ext| /\.#{ext}$/ === file_name }
|
28
|
+
def clear_results
|
29
|
+
@all_files, @matching_files = [], []
|
31
30
|
end
|
32
31
|
|
32
|
+
def file_match_proc
|
33
|
+
method(@search_type ? :full_text_match? : :file_name_match?)
|
34
|
+
end
|
33
35
|
|
34
|
-
def
|
35
|
-
|
36
|
+
def extension_match?(file_path)
|
37
|
+
file_name = File.basename(file_path)
|
38
|
+
!@extensions || @extensions.any? {|ext| /\.#{ext}$/ === file_name }
|
36
39
|
end
|
37
40
|
|
41
|
+
def file_name_match?(file_path)
|
42
|
+
@keywords ? @keywords.any? { |name| /#{name}/ === file_path } : false
|
43
|
+
end
|
38
44
|
|
39
|
-
def
|
40
|
-
if keywords &&
|
45
|
+
def full_text_match?(file_path)
|
46
|
+
if @keywords && !@keywords.empty?
|
41
47
|
file_contents = File.read(file_path)
|
42
|
-
keywords.any? { |key| /#{key}/m === file_contents }
|
48
|
+
@keywords.any? { |key| /#{key}/m === file_contents }
|
43
49
|
else false
|
44
50
|
end
|
45
51
|
end
|
data/lib/fuzzy_notes/notes.rb
CHANGED
@@ -1,104 +1,112 @@
|
|
1
1
|
class FuzzyNotes::Notes
|
2
2
|
include FuzzyNotes::Logger
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
#
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
KEYWORDS = []
|
13
|
-
|
14
|
-
attr_reader :matching_notes, :all_notes
|
15
|
-
|
16
|
-
def initialize(params = {})
|
17
|
-
parse_init_params(params)
|
18
|
-
FuzzyNotes::Log.init_log(@log_level)
|
19
|
-
log.debug "init attributes: \n#{attributes}"
|
20
|
-
|
21
|
-
unless note_paths_valid?
|
22
|
-
log.error "no valid note paths found, exiting"
|
23
|
-
exit
|
24
|
-
end
|
25
|
-
|
26
|
-
@all_notes, @matching_notes = \
|
27
|
-
FuzzyNotes::FuzzyFinder.find(@note_paths, { :keywords => @keywords,
|
28
|
-
:extensions => @extensions,
|
29
|
-
:full_text_search => params[:full_text_search] })
|
4
|
+
module Defaults
|
5
|
+
LOG_LEVEL = 1
|
6
|
+
EDITOR='vim'
|
7
|
+
NOTE_PATHS=[ "#{ENV['HOME']}/notes" ]
|
8
|
+
VALID_EXTENSIONS=%w( txt enc )
|
9
|
+
KEYWORDS = []
|
10
|
+
|
11
|
+
def self.const_missing(*args); end
|
30
12
|
end
|
31
13
|
|
32
|
-
|
33
|
-
#
|
34
|
-
def cat
|
35
|
-
matching_notes.each do |n|
|
36
|
-
puts "=== #{n} ===\n\n"
|
37
|
-
puts "#{File.read(n)}\n"
|
38
|
-
end
|
39
|
-
end
|
14
|
+
OPTS = [:log_level, :editor, :note_paths, :valid_extensions, :keywords].freeze
|
40
15
|
|
16
|
+
attr_reader :matching_notes, :all_notes
|
41
17
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
end
|
18
|
+
def initialize(params = {})
|
19
|
+
parse_init_params(params)
|
20
|
+
FuzzyNotes::Log.init_log(@log_level)
|
21
|
+
log.debug "init attributes: \n#{inspect_instance_vars}"
|
47
22
|
|
23
|
+
unless note_paths_valid?
|
24
|
+
log.error "no valid note paths found, exiting"
|
25
|
+
exit
|
26
|
+
end
|
48
27
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
28
|
+
finder = FuzzyNotes::FuzzyFinder.new(@note_paths,
|
29
|
+
{ :keywords => @keywords,
|
30
|
+
:extensions => @extensions,
|
31
|
+
:full_text_search => params[:full_text_search] })
|
32
|
+
@all_notes, @matching_notes = finder.all_files, finder.matching_files
|
33
|
+
end
|
54
34
|
|
35
|
+
# initialize params or use defaults
|
36
|
+
#
|
37
|
+
def parse_init_params(params)
|
38
|
+
OPTS.each do |param|
|
39
|
+
klass = self.class
|
40
|
+
klass.send(:attr_reader, param)
|
41
|
+
default_const = param.to_s.upcase
|
42
|
+
instance_variable_set("@#{param}", params[param] || Defaults.const_get(default_const) )
|
43
|
+
end
|
44
|
+
end
|
45
|
+
private :parse_init_params
|
46
|
+
|
47
|
+
# dump all matching notes to stdout
|
48
|
+
#
|
49
|
+
def cat
|
50
|
+
matching_notes.each do |note_path|
|
51
|
+
contents = \
|
52
|
+
if encrypted?(note_path)
|
53
|
+
puts "decrypting #{note_path}"
|
54
|
+
FuzzyNotes::Cipher.new.decrypt(note_path)
|
55
|
+
else
|
56
|
+
File.read(note_path)
|
57
|
+
end
|
58
|
+
|
59
|
+
puts "=== #{note_path} ===\n\n"
|
60
|
+
puts "#{contents}\n"
|
61
|
+
end
|
62
|
+
end
|
55
63
|
|
56
|
-
#
|
57
|
-
#
|
58
|
-
def
|
59
|
-
|
60
|
-
end
|
64
|
+
# edit all matching notes in EDITOR
|
65
|
+
#
|
66
|
+
def edit
|
67
|
+
exec("#{editor} #{bashify_paths(matching_notes)}") unless matching_notes.empty?
|
68
|
+
end
|
61
69
|
|
70
|
+
# encrypt matching notes
|
71
|
+
#
|
72
|
+
def encrypt
|
73
|
+
FuzzyNotes::Cipher.new.encrypt(matching_notes, :replace => true)
|
74
|
+
end
|
62
75
|
|
63
|
-
#
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
end
|
76
|
+
# decrypt matching notes
|
77
|
+
#
|
78
|
+
def decrypt
|
79
|
+
FuzzyNotes::Cipher.new.decrypt(matching_notes, :replace => true)
|
80
|
+
end
|
68
81
|
|
82
|
+
# view WC info for all/matching notes
|
83
|
+
#
|
84
|
+
def info
|
85
|
+
paths = bashify_paths(matching_notes.empty? ? all_notes : matching_notes)
|
86
|
+
puts `wc $(find #{paths} -type f)`
|
87
|
+
end
|
69
88
|
|
70
89
|
private
|
71
90
|
|
72
|
-
|
73
|
-
|
74
|
-
#
|
75
|
-
|
76
|
-
INIT_PARAMS.each do |param|
|
77
|
-
klass = self.class
|
78
|
-
klass.send(:attr_reader, param)
|
79
|
-
const_name = param.to_s.upcase
|
80
|
-
instance_variable_set("@#{param}", params[param] ||
|
81
|
-
(klass.const_defined?(const_name) ? klass.const_get(const_name) : nil) )
|
91
|
+
def note_paths_valid?
|
92
|
+
@note_paths.any? do |p|
|
93
|
+
File.exists?(p) || log.info("Warning: note path '#{p}' not found")
|
94
|
+
end
|
82
95
|
end
|
83
|
-
end
|
84
|
-
|
85
96
|
|
86
|
-
|
87
|
-
|
88
|
-
|
97
|
+
# bash style, space seperated fashion
|
98
|
+
#
|
99
|
+
def bashify_paths(paths)
|
100
|
+
paths.map {|n| "\"#{n}\""}.join(' ')
|
89
101
|
end
|
90
|
-
end
|
91
|
-
|
92
|
-
|
93
|
-
# lists matching note paths in bash style, space seperated fashion
|
94
|
-
def bashify_paths(paths)
|
95
|
-
paths.map {|n| "\"#{n}\""}.join(' ')
|
96
|
-
end
|
97
102
|
|
103
|
+
def inspect_instance_vars
|
104
|
+
instance_variables.inject("") { |s, ivar| s << " #{ivar} => #{eval(ivar).inspect}\n" }
|
105
|
+
end
|
98
106
|
|
99
|
-
def
|
100
|
-
|
101
|
-
end
|
107
|
+
def encrypted?(path)
|
108
|
+
File.extname(path)[1..-1] == FuzzyNotes::Cipher::CIPHERTEXT_EXT
|
109
|
+
end
|
102
110
|
|
103
111
|
|
104
112
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fuzzy_notes
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 21
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 5
|
10
|
+
version: 0.0.5
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Alex Skryl
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-07-
|
18
|
+
date: 2011-07-20 00:00:00 -05:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -46,7 +46,7 @@ dependencies:
|
|
46
46
|
version: "0"
|
47
47
|
type: :runtime
|
48
48
|
version_requirements: *id002
|
49
|
-
description: A note manager with fuzzy search, full text search, and encryption capabilities
|
49
|
+
description: A note manager with fuzzy search, full text search, evernote support, and encryption capabilities
|
50
50
|
email: rut216@gmail.com
|
51
51
|
executables:
|
52
52
|
- fnote
|
@@ -55,11 +55,11 @@ extensions: []
|
|
55
55
|
extra_rdoc_files: []
|
56
56
|
|
57
57
|
files:
|
58
|
-
- lib/fuzzy_notes
|
59
|
-
- lib/fuzzy_notes/fuzzy_finder.rb
|
58
|
+
- lib/fuzzy_notes.rb
|
60
59
|
- lib/fuzzy_notes/logger.rb
|
60
|
+
- lib/fuzzy_notes/cipher.rb
|
61
61
|
- lib/fuzzy_notes/notes.rb
|
62
|
-
- lib/fuzzy_notes.rb
|
62
|
+
- lib/fuzzy_notes/fuzzy_finder.rb
|
63
63
|
- bin/fnote
|
64
64
|
- README
|
65
65
|
- TODO
|