fuzzy_notes 0.0.3 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
data/TODO CHANGED
@@ -1,3 +1,2 @@
1
1
  TODO
2
2
  -Evernote integration
3
- -On the fly decryption/editing/re-encryption
@@ -1,37 +1,69 @@
1
1
  require 'gibberish'
2
2
 
3
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 "writing #{decrypt ? 'un' : ''}encrypted content to: #{pathname}/#{filename}#{extension}"
20
- File.open("#{pathname}/#{filename}#{extension}", 'w') { |f| f << ciphertext }
21
- log.debug "deleting #{decrypt ? '' : 'un'}encrypted file: #{path}"
22
- File.delete(path)
23
- rescue OpenSSL::Cipher::CipherError => e
24
- log.error e
25
- end
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
- def self.get_password
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
- extend FuzzyNotes::Logger
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 self.find(path, params = {})
9
- keywords, extensions, search = params.values_at(:keywords, :extensions, :full_text_search)
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
- all_files, matching_files = [], []
14
- Find.find(*path) do |file_path|
15
- if extension_match?(file_path, extensions)
16
- all_files << file_path
17
- matching_files << file_path if match_proc.call(file_path, keywords)
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
- def self.extension_match?(file_path, extensions)
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 self.file_name_match?(file_path, keywords)
35
- keywords ? keywords.any? { |name| /#{name}/ === file_path } : false
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 self.full_text_match?(file_path, keywords)
40
- if keywords && !keywords.empty?
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
@@ -1,104 +1,112 @@
1
1
  class FuzzyNotes::Notes
2
2
  include FuzzyNotes::Logger
3
3
 
4
- INIT_PARAMS = :log_level, :editor, :note_paths, :valid_extensions, :keywords
5
-
6
- # param defaults
7
- #
8
- LOG_LEVEL = 1
9
- EDITOR='vim'
10
- NOTE_PATHS=[ "#{ENV['HOME']}/notes" ]
11
- VALID_EXTENSIONS=%w( txt enc )
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
- # dump all matching notes to stdout
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
- # edit all matching notes in EDITOR
43
- #
44
- def edit
45
- exec("#{editor} #{bashify_paths(matching_notes)}") if !matching_notes.empty?
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
- # encrypt matching notes
50
- #
51
- def encrypt
52
- FuzzyNotes::Cipher.apply_cipher(matching_notes)
53
- end
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
- # decrypt matching notes
57
- #
58
- def decrypt
59
- FuzzyNotes::Cipher.apply_cipher(matching_notes, true)
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
- # view WC info for all/matching notes
64
- def info
65
- paths = bashify_paths(matching_notes.empty? ? all_notes : matching_notes)
66
- puts `wc $(find #{paths} -type f)`
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
- # 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) )
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
- def note_paths_valid?
87
- @note_paths.any? do |p|
88
- File.exists?(p) || log.info("Warning: note path '#{p}' not found")
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 attributes
100
- instance_variables.inject("") { |s, ivar| s << " #{ivar} => #{eval(ivar).inspect}\n" }
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: 25
4
+ hash: 21
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 3
10
- version: 0.0.3
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-19 00:00:00 -05:00
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/cipher.rb
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