fuzzy_notes 0.1.3 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -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