fuzzy_notes 0.1.3 → 0.1.4

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.
@@ -0,0 +1,54 @@
1
+ ## About
2
+
3
+ *fuzzy_notes* is a command line document viewer with some cool features:
4
+
5
+ 1. Supports Emacs/Vim/MacVim and other CLI text editors
6
+ 2. Supports viewing image files using a user specified CLI viewer (eg. open, display)
7
+ 3. Fuzzy path search and full text search across one or more note directories
8
+ 4. OpenSSL encryption for text notes
9
+ 5. Evernote synchronization
10
+
11
+
12
+ ## Configuration
13
+
14
+ *fuzzy_notes* looks for a ~/.fuzzy_notes config file or the -c option and a
15
+ config file path. A config file is not required if you're ok with the default
16
+ settings:
17
+
18
+ :editor: vim
19
+ :viewer: open
20
+ :valid_extensions: ["txt", "enc", "txt", "html", "tif", "tiff", "gif", "jpeg", "jpg", "png", "pdf"]
21
+ :verbose: false
22
+ :full_text_search: false
23
+ :note_paths:
24
+ - ~/notes
25
+
26
+ An Evernote section is required in the config file in order to use the evernote sync tool
27
+
28
+ :evernote:
29
+ :note_path: [local directory used to sync evernotes]
30
+ :username: [evernote username]
31
+ :consumer_key: [consumer key acquired through Evernote dev channel]
32
+ :consumer_secret: [consumer secret acquired through Evernote dev channel]
33
+
34
+ You need to get a "client application" API key from [Evernote](http://www.evernote.com/about/developer/api/#key),
35
+ note that a "web application" API key uses OAuth to authenticate and will not work.
36
+
37
+
38
+ ## Usage
39
+
40
+ Usage: fnote [options] [keyword1, keyword2...]
41
+ -c, --config [CONFIG] Specify config file
42
+ -t, --editor [EDITOR] Editor of choice
43
+ -a, --add-path [PATH] Add a note path to the config file
44
+ -r, --rm-path [PATH] Remove a note path from the config file
45
+ -s, --search Perform a full text search when matching notes
46
+ -p, --preview Dump matching notes to stdout or preview images
47
+ -l, --list List all or matching notes
48
+ -i, --info Show stats for matching notes
49
+ -e, --encrypt Encrypt matching notes
50
+ -d, --decrypt Decrypt matching notes
51
+ -v, --verbose Enable debug output
52
+ -u, --update-evernotes Synchronize evernote directory
53
+ --no-color Turn off ANSI color
54
+ -h, --help Show usage
data/TODO CHANGED
@@ -1,8 +1,6 @@
1
1
  TODO
2
- - README
2
+ - ability to create notes
3
3
  - ask for missing params during evernote AUTH
4
4
  - debugging output
5
5
  - figure out good output spacing
6
- - test suite
7
- - 1.9 testing
8
6
  - add a per-note password option for enc/dec
data/bin/fnote CHANGED
@@ -1,6 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- # test without installing gem
4
3
  $LOAD_PATH.unshift "#{File.dirname(File.expand_path(__FILE__))}/../lib/"
5
4
 
6
5
  require 'optparse'
@@ -9,25 +8,26 @@ require 'rubygems'
9
8
  require 'fuzzy_notes'
10
9
 
11
10
  CONFIG_PATH = "#{ENV['HOME']}/.fuzzy_notes"
12
- OPT_ACTIONS = [:print, :list, :info, :encrypt, :decrypt, :update_evernotes].freeze
13
- OPT_KEYWORDS_REQUIRED = [:print, :edit, :encrypt, :decrypt].freeze
11
+ OPT_ACTIONS = [:add_path, :rm_path, :preview, :list, :info, :encrypt, :decrypt, :update_evernotes].freeze
12
+ OPT_KEYWORDS_REQUIRED = [:preview, :edit, :encrypt, :decrypt].freeze
14
13
 
15
14
  options = {}
16
15
  optparse = OptionParser.new do |opts|
17
16
  opts.banner = "Usage: fnote [options] [keyword1, keyword2...]"
18
17
 
19
- opts.on("-c", "--config [CONFIG]", "Specify config file") { |opt| options[:config] = opt}
20
- opts.on("-n", "--note-path [PATH]", "Specify config file") { |opt| options[:note_path] = opt}
21
- opts.on("--editor [EDITOR]", "Editor of choice") { |opt| options[:editor] = opt}
22
- opts.on("-s", "--search", "Perform a full text search when matching notes") { |opt| options[:search] = true}
23
- opts.on("-p", "--print", "Dump matching notes to stdout") { |opt| options[:print] = true }
18
+ opts.on("-c", "--config [CONFIG]", "Specify config file") { |opt| options[:config] = opt }
19
+ opts.on("-t", "--editor [EDITOR]", "Editor of choice") { |opt| options[:editor] = opt }
20
+ opts.on("-a", "--add-path [PATH]", "Add a note path to the config file") { |opt| options[:add_path] = opt }
21
+ opts.on("-r", "--rm-path [PATH]", "Remove a note path from the config file") { |opt| options[:rm_path] = opt }
22
+ opts.on("-s", "--search", "Perform a full text search when matching notes") { |opt| options[:search] = true }
23
+ opts.on("-p", "--preview", "Dump matching notes to stdout or preview images") { |opt| options[:preview] = true }
24
24
  opts.on("-l", "--list", "List all or matching notes") { |opt| options[:list] = true }
25
- opts.on("-i", "--info", "Show statistics for matching notes") { |opt| options[:info] = true }
25
+ opts.on("-i", "--info", "Show stats for matching notes") { |opt| options[:info] = true }
26
26
  opts.on("-e", "--encrypt", "Encrypt matching notes") { |opt| options[:encrypt] = true }
27
27
  opts.on("-d", "--decrypt", "Decrypt matching notes") { |opt| options[:decrypt] = true }
28
28
  opts.on("-v", "--verbose", "Enable debug output") { |opt| options[:verbose] = true }
29
- opts.on("--no-color", "Turn off ANSI color") { |opt| options[:no_color] = true}
30
29
  opts.on("-u", "--update-evernotes", "Synchronize evernote directory") { |opt| options[:update_evernotes] = true }
30
+ opts.on("--no-color", "Turn off ANSI color") { |opt| options[:no_color] = true }
31
31
  opts.on("-h", "--help", "Show usage") {
32
32
  puts opts
33
33
  exit
@@ -56,11 +56,29 @@ config_path = \
56
56
  config = config_path ? YAML::load_file(config_path) : {}
57
57
  log.info("config file not found, using defaults") if config.empty?
58
58
 
59
- # grab notes
59
+ # add/remove note path from config
60
+ #
61
+ if options[:add_path] || options[:rm_path]
62
+ if options[:add_path]
63
+ full_path = File.expand_path(options[:add_path])
64
+ config[:note_paths] = (Array(config[:note_paths]) + Array(full_path)).uniq
65
+ puts "added '#{full_path}' to note paths"
66
+ else
67
+ full_path = File.expand_path(options[:rm_path])
68
+ config[:note_paths].reject! { |p| p == full_path }
69
+ puts "removed '#{full_path}' from note paths"
70
+ end
71
+
72
+ File.open(config_path, 'w') { |f| f << config.to_yaml }
73
+ exit
74
+ end
75
+
76
+ # process notes
60
77
  #
61
78
  notes = FuzzyNotes::Notes.new(:editor => options[:editor] || config[:editor],
62
- :valid_extensions => config[:valid_extensions],
63
- :note_paths => [options[:note_path] || config[:note_paths]].flatten,
79
+ :viewer => config[:viewer],
80
+ :custom_extensions => config[:custom_extensions],
81
+ :note_paths => config[:note_paths].flatten,
64
82
  :evernote_params => config[:evernote],
65
83
  :full_text_search => options[:search] || config[:full_text_search],
66
84
  :log_level => (options[:verbose] || config[:verbose]) ? :debug : :info,
@@ -75,12 +93,12 @@ elsif options[:update_evernotes]
75
93
  notes.evernote_sync
76
94
  elsif options[:info]
77
95
  notes.info
78
- elsif options[:print]
96
+ elsif options[:preview]
79
97
  notes.cat
80
98
  elsif options[:encrypt]
81
99
  notes.encrypt
82
100
  elsif options[:decrypt]
83
101
  notes.decrypt
84
- else
102
+ else
85
103
  notes.edit
86
104
  end
@@ -1,6 +1,3 @@
1
- require 'pp'
2
- require 'rubygems'
3
-
4
1
  module FuzzyNotes; end
5
2
 
6
3
  require 'fuzzy_notes/logger'
@@ -8,4 +5,6 @@ require 'fuzzy_notes/authentication'
8
5
  require 'fuzzy_notes/cipher'
9
6
  require 'fuzzy_notes/evernote_sync'
10
7
  require 'fuzzy_notes/fuzzy_finder'
8
+ require 'fuzzy_notes/text_viewer'
9
+ require 'fuzzy_notes/image_viewer'
11
10
  require 'fuzzy_notes/notes'
@@ -0,0 +1,12 @@
1
+ class FuzzyNotes::ImageViewer
2
+ IMG_EXTS = ['tif', 'tiff', 'gif', 'jpeg', 'jpg', 'png', 'pdf']
3
+
4
+ def self.display(viewer, path)
5
+ `#{viewer} #{path}`
6
+ end
7
+
8
+ def self.image?(path)
9
+ IMG_EXTS.include?(File.extname(path)[1..-1])
10
+ end
11
+
12
+ end
@@ -1,37 +1,40 @@
1
1
  require 'tempfile'
2
2
 
3
- class FuzzyNotes::Notes
4
- include FuzzyNotes::Logger
5
-
6
- module Defaults
3
+ module FuzzyNotes::Defaults
7
4
  LOG_LEVEL = :info
8
5
  EDITOR = 'vim'
6
+ VIEWER = 'open'
9
7
  KEYWORDS = []
10
8
  NOTE_PATHS = [ "#{ENV['HOME']}/notes" ]
11
- VALID_EXTENSIONS = [ 'txt',
9
+ FULL_TEXT_SEARCH = false
10
+ VALID_EXTENSIONS = [ FuzzyNotes::TextViewer::TXT_EXT,
12
11
  FuzzyNotes::Cipher::CIPHERTEXT_EXT,
13
12
  FuzzyNotes::Cipher::PLAINTEXT_EXT,
14
- FuzzyNotes::EvernoteSync::NOTE_EXT ]
13
+ FuzzyNotes::EvernoteSync::NOTE_EXT] +
14
+ FuzzyNotes::ImageViewer::IMG_EXTS
15
15
 
16
16
  def self.const_missing(*args); end
17
17
  end
18
18
 
19
- VALID_PARAMS = [:log_level, :color, :editor, :note_paths, :valid_extensions, :keywords, :evernote_params].freeze
19
+ class FuzzyNotes::Notes
20
+ include FuzzyNotes::Logger
21
+
22
+ VALID_PARAMS = [:log_level, :color, :editor, :viewer, :note_paths,
23
+ :valid_extensions, :custom_extensions, :full_text_search,
24
+ :keywords, :evernote_params].freeze
20
25
 
21
26
  attr_reader :matching_notes, :all_notes
22
27
 
23
28
  def initialize(params = {})
24
- parse_init_params(params)
25
- FuzzyNotes::Log.init_log(@log_level, @color)
26
- log.debug "init params: \n#{inspect_instance_vars}"
27
- @note_paths = prune_invalid_note_paths!
28
-
29
- finder = FuzzyNotes::FuzzyFinder.new(@note_paths,
30
- { :keywords => @keywords,
31
- :extensions => @valid_extensions,
32
- :full_text_search => params[:full_text_search] })
33
- @all_notes, @matching_notes = finder.files_matching_extension, finder.files_matching_all
34
- @cipher = FuzzyNotes::Cipher.new
29
+ @params = params
30
+ parse_init_params
31
+
32
+ init_logger
33
+ init_cipher
34
+ init_finder
35
+
36
+ @all_notes = @finder.files_matching_extension
37
+ @matching_notes = @finder.files_matching_all
35
38
  end
36
39
 
37
40
  # dump all matching notes to stdout
@@ -48,8 +51,10 @@ end
48
51
  decrypted_notes.shift
49
52
  elsif FuzzyNotes::EvernoteSync.evernote?(note_path)
50
53
  FuzzyNotes::EvernoteSync.sanitize_evernote(note_path)
54
+ elsif FuzzyNotes::ImageViewer.image?(note_path)
55
+ FuzzyNotes::ImageViewer.display(@viewer, note_path)
51
56
  else
52
- File.read(note_path)
57
+ FuzzyNotes::TextViewer.read(note_path)
53
58
  end
54
59
 
55
60
  if contents
@@ -73,7 +78,7 @@ end
73
78
 
74
79
  # edit decrypted files
75
80
  unless notes_to_edit.empty?
76
- system("#{editor} #{bashify_note_paths(notes_to_edit)}")
81
+ system("#{@editor} #{bashify_note_paths(notes_to_edit)}")
77
82
  end
78
83
 
79
84
  # reencrypt decrypted notes
@@ -127,6 +132,36 @@ end
127
132
 
128
133
  private
129
134
 
135
+ # initialize to params or use defaults
136
+ #
137
+ def parse_init_params
138
+ VALID_PARAMS.each do |param|
139
+ default_const = param.to_s.upcase
140
+
141
+ val = @params[param] || FuzzyNotes::Defaults.const_get(default_const)
142
+ instance_variable_set("@#{param}", val)
143
+ end
144
+ end
145
+
146
+ def init_logger
147
+ FuzzyNotes::Log.init_log(@log_level, @color)
148
+ end
149
+
150
+ def init_cipher
151
+ @cipher = FuzzyNotes::Cipher.new
152
+ end
153
+
154
+ def init_finder
155
+ @finder = FuzzyNotes::FuzzyFinder.new(valid_note_paths,
156
+ { :keywords => @keywords,
157
+ :extensions => valid_extensions,
158
+ :full_text_search => @full_text_search })
159
+ end
160
+
161
+ def valid_extensions
162
+ (@valid_extensions + @custom_extensions).uniq
163
+ end
164
+
130
165
  def encrypted_notes
131
166
  @encrypted_notes ||= matching_notes.select { |note_path| FuzzyNotes::Cipher.encrypted?(note_path) }
132
167
  end
@@ -137,10 +172,11 @@ private
137
172
 
138
173
  def plaintext_notes
139
174
  @plaintext_notes ||= matching_notes.select { |note_path| !FuzzyNotes::Cipher.encrypted?(note_path) &&
140
- !FuzzyNotes::EvernoteSync.evernote?(note_path) }
175
+ !FuzzyNotes::EvernoteSync.evernote?(note_path) &&
176
+ !FuzzyNotes::ImageViewer.image?(note_path) }
141
177
  end
142
178
 
143
- def prune_invalid_note_paths!
179
+ def valid_note_paths
144
180
  valid_paths = []
145
181
  @note_paths.each do |path|
146
182
  if File.directory?(path)
@@ -149,10 +185,12 @@ private
149
185
  log.warn("note path #{PATH_COLOR} #{path} #{DEFAULT_COLOR} does not exist")
150
186
  end
151
187
  end
188
+
152
189
  if valid_paths.empty?
153
190
  log.error "no valid note paths found, exiting"
154
191
  exit
155
192
  end
193
+
156
194
  valid_paths
157
195
  end
158
196
 
@@ -177,6 +215,7 @@ private
177
215
  notes << encrypted_notes if params[:encrypted]
178
216
  notes << evernote_notes if params[:evernote]
179
217
  notes << plaintext_notes if params[:plaintext]
218
+
180
219
  if notes.empty?
181
220
  notes << matching_notes(:all_if_empty => true)
182
221
  end
@@ -191,26 +230,4 @@ private
191
230
  (@matching_notes.empty? && params[:all_if_empty]) ? @all_notes : @matching_notes
192
231
  end
193
232
 
194
- # initialize to params or use defaults
195
- #
196
- def parse_init_params(params)
197
- VALID_PARAMS.each do |param|
198
- klass = self.class
199
- klass.send(:attr_reader, param)
200
- default_const = param.to_s.upcase
201
-
202
- value = \
203
- if params.include?(param)
204
- params[param]
205
- else Defaults.const_get(default_const)
206
- end
207
- instance_variable_set("@#{param}", value)
208
- end
209
- end
210
-
211
- def inspect_instance_vars
212
- instance_variables.inject("") { |s, ivar| s << " #{ivar} => #{eval(ivar.to_s).inspect}\n" }
213
- end
214
-
215
-
216
233
  end
@@ -0,0 +1,8 @@
1
+ class FuzzyNotes::TextViewer
2
+ FuzzyNotes::TextViewer::TXT_EXT = 'txt'
3
+
4
+ def self.read(path)
5
+ File.read(path)
6
+ end
7
+
8
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fuzzy_notes
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.1.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-05-16 00:00:00.000000000 Z
12
+ date: 2012-09-09 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: buffered_logger
16
- requirement: &70250716786780 !ruby/object:Gem::Requirement
16
+ requirement: !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,15 @@ dependencies:
21
21
  version: 0.1.2
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70250716786780
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: 0.1.2
25
30
  - !ruby/object:Gem::Dependency
26
31
  name: gibberish
27
- requirement: &70250716786180 !ruby/object:Gem::Requirement
32
+ requirement: !ruby/object:Gem::Requirement
28
33
  none: false
29
34
  requirements:
30
35
  - - ! '>='
@@ -32,10 +37,15 @@ dependencies:
32
37
  version: '0'
33
38
  type: :runtime
34
39
  prerelease: false
35
- version_requirements: *70250716786180
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
36
46
  - !ruby/object:Gem::Dependency
37
47
  name: evernote
38
- requirement: &70250716801860 !ruby/object:Gem::Requirement
48
+ requirement: !ruby/object:Gem::Requirement
39
49
  none: false
40
50
  requirements:
41
51
  - - ! '>='
@@ -43,10 +53,15 @@ dependencies:
43
53
  version: '0'
44
54
  type: :runtime
45
55
  prerelease: false
46
- version_requirements: *70250716801860
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
47
62
  - !ruby/object:Gem::Dependency
48
63
  name: sanitize
49
- requirement: &70250716801020 !ruby/object:Gem::Requirement
64
+ requirement: !ruby/object:Gem::Requirement
50
65
  none: false
51
66
  requirements:
52
67
  - - ! '>='
@@ -54,7 +69,12 @@ dependencies:
54
69
  version: '0'
55
70
  type: :runtime
56
71
  prerelease: false
57
- version_requirements: *70250716801020
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
58
78
  description: A note manager with fuzzy path search, full text search, evernote sync,
59
79
  and encryption capabilities
60
80
  email: rut216@gmail.com
@@ -67,11 +87,13 @@ files:
67
87
  - lib/fuzzy_notes/cipher.rb
68
88
  - lib/fuzzy_notes/evernote_sync.rb
69
89
  - lib/fuzzy_notes/fuzzy_finder.rb
90
+ - lib/fuzzy_notes/image_viewer.rb
70
91
  - lib/fuzzy_notes/logger.rb
71
92
  - lib/fuzzy_notes/notes.rb
93
+ - lib/fuzzy_notes/text_viewer.rb
72
94
  - lib/fuzzy_notes.rb
73
95
  - bin/fnote
74
- - README
96
+ - README.md
75
97
  - TODO
76
98
  homepage: http://github.com/skryl
77
99
  licenses: []
@@ -93,7 +115,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
93
115
  version: '0'
94
116
  requirements: []
95
117
  rubyforge_project:
96
- rubygems_version: 1.8.15
118
+ rubygems_version: 1.8.23
97
119
  signing_key:
98
120
  specification_version: 3
99
121
  summary: A cli note manager
data/README DELETED
@@ -1,53 +0,0 @@
1
- ABOUT
2
- -------------------------------------------------------------------------
3
- fuzzy_notes is a command line note manager with some cool features:
4
-
5
- 1. Supports Emacs/Vim/MacVim and other CLI text editors
6
- 2. Fuzzy path search and full text search across one or more note directories
7
- 3. OpenSSL encryption
8
- 4. Evernote synchronization
9
-
10
-
11
- CONFIG
12
- -------------------------------------------------------------------------
13
-
14
- fuzzy_notes looks for a ~/.fuzzy_notes config file or the -c option and
15
- overwrites the defaults with the contents of the YAML file specified.
16
-
17
- A config file is not required if you're ok with fuzzy_note's defaults settings
18
- outlined below:
19
-
20
- :editor: vim
21
- :verbose: false
22
- :full_text_search: false
23
- :note_paths:
24
- - [HOMEDIR]/notes
25
-
26
- An Evernote config section is required to use the sync tool
27
-
28
- :evernote:
29
- :note_path: [local directory used to sync evernotes]
30
- :username: [evernote username]
31
- :consumer_key: [consumer key acquired through Evernote dev channel]
32
- :consumer_secret: [consumer secret acquired through Evernote dev channel]
33
-
34
- Get yourself a "client application" API key from Evernote
35
- (http://www.evernote.com/about/developer/api/#key), note that a "web
36
- application" API key uses OAuth to authenticate and will not work.
37
-
38
-
39
- USAGE
40
- -------------------------------------------------------------------------
41
-
42
- fnote [options] [keyword1, keyword2...]
43
- -c, --config [CONFIG] Specify config file
44
- -p, --print Dump matching notes to stdout
45
- -l, --list List matching notes
46
- -i, --info Show statistics for matching notes
47
- -s, --search Perform a full text search when matching notes
48
- -v, --verbose Enable debug output
49
- -e, --encrypt Encrypt matching notes
50
- -d, --decrypt Decrypt matching notes
51
- -n, --no-color Turn off ANSI color
52
- -u, --evernote-update Synchronize evernote directory
53
- -h, --help Show this message