fuzzy_notes 0.0.1 → 0.0.2
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/bin/fnote +14 -2
- data/lib/fuzzy_notes.rb +1 -0
- data/lib/fuzzy_notes/cipher.rb +37 -0
- data/lib/fuzzy_notes/fuzzy_finder.rb +6 -0
- data/lib/fuzzy_notes/logger.rb +2 -2
- data/lib/fuzzy_notes/notes.rb +37 -49
- metadata +6 -5
data/bin/fnote
CHANGED
@@ -1,5 +1,8 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
+
# test without installing gem
|
4
|
+
#$LOAD_PATH.unshift "#{File.dirname(File.expand_path(__FILE__))}/../lib/"
|
5
|
+
|
3
6
|
require 'optparse'
|
4
7
|
require 'yaml'
|
5
8
|
require 'rubygems'
|
@@ -8,7 +11,6 @@ require 'fuzzy_notes'
|
|
8
11
|
CONFIG_PATH = "#{ENV['HOME']}/.fuzzy_notes"
|
9
12
|
|
10
13
|
options = {}
|
11
|
-
need_extra_args = [:print, :edit, :encrypt, :decrypt]
|
12
14
|
optparse = OptionParser.new do |opts|
|
13
15
|
opts.banner = "Usage: fnote [options] [keyword1, keyword2...]"
|
14
16
|
|
@@ -26,10 +28,14 @@ optparse = OptionParser.new do |opts|
|
|
26
28
|
}
|
27
29
|
end
|
28
30
|
|
31
|
+
need_extra_args = [:print, :edit, :encrypt, :decrypt]
|
32
|
+
|
29
33
|
begin
|
30
34
|
optparse.parse!(ARGV)
|
35
|
+
# edit is the default action
|
31
36
|
options[:edit] = true if options.values.compact.empty?
|
32
|
-
|
37
|
+
|
38
|
+
# check for required args
|
33
39
|
if need_extra_args.any? {|opt| options[opt]} && ARGV.empty?
|
34
40
|
puts optparse
|
35
41
|
exit
|
@@ -38,6 +44,8 @@ rescue OptionParser::ParseError => e
|
|
38
44
|
puts optparse
|
39
45
|
end
|
40
46
|
|
47
|
+
# fetch config
|
48
|
+
#
|
41
49
|
config_path = \
|
42
50
|
options[:config] && File.exists?(options[:config]) && options[:config] ||
|
43
51
|
File.exists?(CONFIG_PATH) && CONFIG_PATH
|
@@ -45,11 +53,15 @@ config_path = \
|
|
45
53
|
config = config_path ? YAML::load_file(config_path) : {}
|
46
54
|
puts "Warning: config file not found, using defaults" if config.empty?
|
47
55
|
|
56
|
+
# find matching notes
|
57
|
+
#
|
48
58
|
notes = FuzzyNotes::Notes.new(:log_level => (options[:verbose] || config[:verbose]) ? 0 : 1,
|
49
59
|
:note_paths => config[:note_paths],
|
50
60
|
:full_text_search => options[:search] || config[:full_text_search],
|
51
61
|
:keywords => ARGV)
|
52
62
|
|
63
|
+
# perform action on matching notes
|
64
|
+
#
|
53
65
|
if options[:list] || options[:info]
|
54
66
|
notes.info
|
55
67
|
elsif options[:print]
|
data/lib/fuzzy_notes.rb
CHANGED
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'gibberish'
|
2
|
+
|
3
|
+
class FuzzyNotes::Cipher
|
4
|
+
extend FuzzyNotes::Logger
|
5
|
+
private_class_method :new
|
6
|
+
|
7
|
+
def self.apply_cipher(file_paths, decrypt = false)
|
8
|
+
extension, action = decrypt ? ['.txt', 'dec'] : ['.enc', 'enc']
|
9
|
+
password = get_password
|
10
|
+
cipher = Gibberish::AES.new(password)
|
11
|
+
|
12
|
+
file_paths.each do |path|
|
13
|
+
log.info "#{action} '#{path}'"
|
14
|
+
pathname = File.dirname(path)
|
15
|
+
filename = File.basename(path, '.*')
|
16
|
+
|
17
|
+
begin
|
18
|
+
ciphertext = cipher.send(action, File.read(path))
|
19
|
+
log.debug "[debug] writing encrypted content to: #{pathname}/#{filename}#{extension}"
|
20
|
+
File.open("#{pathname}/#{filename}#{extension}", 'w') { |f| f << ciphertext }
|
21
|
+
log.debug "[debug] deleting unencrypted file: #{path}"
|
22
|
+
File.delete(path)
|
23
|
+
rescue OpenSSL::Cipher::CipherError => e
|
24
|
+
log.error "ERROR: #{e}"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
def self.get_password
|
31
|
+
printf 'Enter password (will not be shown):'
|
32
|
+
`stty -echo`; password = STDIN.gets.strip;`stty echo`; puts
|
33
|
+
log.debug "[debug] entered password: #{password.inspect}"
|
34
|
+
password
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
@@ -4,6 +4,7 @@ class FuzzyNotes::FuzzyFinder
|
|
4
4
|
extend FuzzyNotes::Logger
|
5
5
|
private_class_method :new
|
6
6
|
|
7
|
+
|
7
8
|
def self.find(path, params = {})
|
8
9
|
keywords, extensions, search = params.values_at(:keywords, :extensions, :full_text_search)
|
9
10
|
match_proc = method(search ? :full_text_match? : :file_name_match?)
|
@@ -20,17 +21,21 @@ class FuzzyNotes::FuzzyFinder
|
|
20
21
|
[all_files.sort, matching_files.sort]
|
21
22
|
end
|
22
23
|
|
24
|
+
|
23
25
|
private
|
24
26
|
|
27
|
+
|
25
28
|
def self.extension_match?(file_path, extensions)
|
26
29
|
file_name = File.basename(file_path)
|
27
30
|
!extensions || extensions.any? {|ext| /\.#{ext}$/ === file_name }
|
28
31
|
end
|
29
32
|
|
33
|
+
|
30
34
|
def self.file_name_match?(file_path, keywords)
|
31
35
|
keywords ? keywords.any? { |name| /#{name}/ === file_path } : false
|
32
36
|
end
|
33
37
|
|
38
|
+
|
34
39
|
def self.full_text_match?(file_path, keywords)
|
35
40
|
if keywords && !keywords.empty?
|
36
41
|
file_contents = File.read(file_path)
|
@@ -39,4 +44,5 @@ private
|
|
39
44
|
end
|
40
45
|
end
|
41
46
|
|
47
|
+
|
42
48
|
end
|
data/lib/fuzzy_notes/logger.rb
CHANGED
@@ -1,9 +1,8 @@
|
|
1
1
|
require 'buffered_logger'
|
2
2
|
|
3
3
|
class FuzzyNotes::Log
|
4
|
-
LOG_LEVEL = 1
|
5
|
-
|
6
4
|
private_class_method :new
|
5
|
+
LOG_LEVEL = 1
|
7
6
|
|
8
7
|
def self.init_log(log_level)
|
9
8
|
@log = BufferedLogger.new(STDOUT, log_level)
|
@@ -14,6 +13,7 @@ class FuzzyNotes::Log
|
|
14
13
|
end
|
15
14
|
end
|
16
15
|
|
16
|
+
|
17
17
|
module FuzzyNotes::Logger
|
18
18
|
def log
|
19
19
|
FuzzyNotes::Log.log
|
data/lib/fuzzy_notes/notes.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'gibberish'
|
2
|
-
|
3
1
|
class FuzzyNotes::Notes
|
4
2
|
include FuzzyNotes::Logger
|
5
3
|
|
@@ -13,40 +11,28 @@ NOTE_PATHS=[ "#{ENV['HOME']}/notes" ]
|
|
13
11
|
VALID_EXTENSIONS=%w( txt enc )
|
14
12
|
KEYWORDS = []
|
15
13
|
|
16
|
-
attr_reader :
|
14
|
+
attr_reader :matching_notes, :all_notes
|
17
15
|
|
18
16
|
def initialize(params = {})
|
19
17
|
parse_init_params(params)
|
18
|
+
FuzzyNotes::Log.init_log(@log_level)
|
19
|
+
log.debug "[debug] init attributes: \n#{attributes}"
|
20
20
|
|
21
|
-
unless
|
22
|
-
log.error "ERROR: no valid note paths found"
|
21
|
+
unless note_paths_valid?
|
22
|
+
log.error "ERROR: no valid note paths found, exiting"
|
23
23
|
exit
|
24
24
|
end
|
25
25
|
|
26
|
-
@all_notes, @
|
26
|
+
@all_notes, @matching_notes = \
|
27
27
|
FuzzyNotes::FuzzyFinder.find(@note_paths, { :keywords => @keywords,
|
28
28
|
:extensions => @extensions,
|
29
29
|
:full_text_search => params[:full_text_search] })
|
30
30
|
end
|
31
31
|
|
32
|
-
|
33
|
-
|
34
|
-
klass = self.class
|
35
|
-
klass.send(:attr_reader, param)
|
36
|
-
const_name = param.to_s.upcase
|
37
|
-
instance_variable_set("@#{param}", params[param] ||
|
38
|
-
(klass.const_defined?(const_name) ? klass.const_get(const_name) : nil) )
|
39
|
-
end
|
40
|
-
FuzzyNotes::Log.init_log(@log_level)
|
41
|
-
|
42
|
-
ivar_values = instance_variables.inject("") { |s, ivar| s << " #{ivar} => #{eval(ivar).inspect}\n" }
|
43
|
-
log.debug "[debug] init attributes: \n#{ivar_values}"
|
44
|
-
end
|
45
|
-
|
46
|
-
|
47
|
-
# cat all matching notes to stdout
|
32
|
+
# dump all matching notes to stdout
|
33
|
+
#
|
48
34
|
def cat
|
49
|
-
|
35
|
+
matching_notes.each do |n|
|
50
36
|
puts "=== #{n} ===\n\n"
|
51
37
|
puts "#{File.read(n)}\n"
|
52
38
|
end
|
@@ -54,24 +40,29 @@ end
|
|
54
40
|
|
55
41
|
|
56
42
|
# edit all matching notes in EDITOR
|
43
|
+
#
|
57
44
|
def edit
|
58
|
-
exec("#{editor} #{bashify_paths(
|
45
|
+
exec("#{editor} #{bashify_paths(matching_notes)}") if !matching_notes.empty?
|
59
46
|
end
|
60
47
|
|
61
48
|
|
49
|
+
# encrypt matching notes
|
50
|
+
#
|
62
51
|
def encrypt
|
63
|
-
apply_cipher
|
52
|
+
FuzzyNotes::Cipher.apply_cipher(matching_notes)
|
64
53
|
end
|
65
54
|
|
66
55
|
|
56
|
+
# decrypt matching notes
|
57
|
+
#
|
67
58
|
def decrypt
|
68
|
-
apply_cipher(true)
|
59
|
+
FuzzyNotes::Cipher.apply_cipher(matching_notes, true)
|
69
60
|
end
|
70
61
|
|
71
62
|
|
72
63
|
# view WC info for all/matching notes
|
73
64
|
def info
|
74
|
-
paths = bashify_paths(
|
65
|
+
paths = bashify_paths(matching_notes.empty? ? all_notes : matching_notes)
|
75
66
|
puts `wc $(find #{paths} -type f)`
|
76
67
|
end
|
77
68
|
|
@@ -79,32 +70,23 @@ end
|
|
79
70
|
private
|
80
71
|
|
81
72
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
ciphertext = cipher.send(action, File.read(note))
|
92
|
-
log.debug "[debug] writing encrypted content to: #{pathname}/#{filename}#{extension}"
|
93
|
-
File.open("#{pathname}/#{filename}#{extension}", 'w') { |f| f << ciphertext }
|
94
|
-
log.debug "[debug] deleting unencrypted file: #{note}"
|
95
|
-
File.delete(note)
|
96
|
-
rescue OpenSSL::Cipher::CipherError => e
|
97
|
-
log.error "ERROR: #{e}"
|
98
|
-
end
|
73
|
+
# initialize params or use defaults
|
74
|
+
#
|
75
|
+
def parse_init_params(params)
|
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) )
|
99
82
|
end
|
100
83
|
end
|
101
84
|
|
102
85
|
|
103
|
-
def
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
password
|
86
|
+
def note_paths_valid?
|
87
|
+
@note_paths.any? do |p|
|
88
|
+
File.exists?(p) || log.info("Warning: note path '#{p}' not found")
|
89
|
+
end
|
108
90
|
end
|
109
91
|
|
110
92
|
|
@@ -113,4 +95,10 @@ def bashify_paths(paths)
|
|
113
95
|
paths.map {|n| "\"#{n}\""}.join(' ')
|
114
96
|
end
|
115
97
|
|
98
|
+
|
99
|
+
def attributes
|
100
|
+
instance_variables.inject("") { |s, ivar| s << " #{ivar} => #{eval(ivar).inspect}\n" }
|
101
|
+
end
|
102
|
+
|
103
|
+
|
116
104
|
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: 27
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 2
|
10
|
+
version: 0.0.2
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Alex Skryl
|
@@ -55,10 +55,11 @@ extensions: []
|
|
55
55
|
extra_rdoc_files: []
|
56
56
|
|
57
57
|
files:
|
58
|
-
- lib/fuzzy_notes
|
58
|
+
- lib/fuzzy_notes.rb
|
59
59
|
- lib/fuzzy_notes/logger.rb
|
60
|
+
- lib/fuzzy_notes/cipher.rb
|
60
61
|
- lib/fuzzy_notes/notes.rb
|
61
|
-
- lib/fuzzy_notes.rb
|
62
|
+
- lib/fuzzy_notes/fuzzy_finder.rb
|
62
63
|
- bin/fnote
|
63
64
|
- README
|
64
65
|
- TODO
|