evernote-jeeves 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +1 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +30 -0
- data/LICENSE.txt +22 -0
- data/README.md +48 -0
- data/Rakefile +1 -0
- data/bin/jeeves +8 -0
- data/config/config.example.yml +2 -0
- data/evernote-jeeves.gemspec +27 -0
- data/lib/evernote/jeeves/version.rb +5 -0
- data/lib/evernote/jeeves.rb +160 -0
- data/pkg/evernote-jeeves-0.0.1.gem +0 -0
- data/version +0 -0
- metadata +114 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: ea7b7a401e272f5a5000e0864f96618a0fa0fa9c
|
4
|
+
data.tar.gz: 798ac8602e52ef53f7559b30fa5cce45ed19e731
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 9b01687db37a7269931492b0d4998f60af44a9bb84f100d0689eda05814edbb24fe61418fb0093d1841e9dc459de55f5db46781cb81b76f8953542e8c0e961ef
|
7
|
+
data.tar.gz: 63918fd4c777d2a70aa6f93bf0ba05c4549404b885143c10f0d211f7efa118848e41787029da49f8a905d663a8ae81731e66b6aa5f61b28f4539c0f14938e638
|
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
config/config.yml
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
evernote-jeeves (0.0.2)
|
5
|
+
evernote-thrift
|
6
|
+
sanitize
|
7
|
+
|
8
|
+
GEM
|
9
|
+
remote: https://rubygems.org/
|
10
|
+
specs:
|
11
|
+
crass (1.0.2)
|
12
|
+
evernote-thrift (1.25.1)
|
13
|
+
mini_portile (0.6.2)
|
14
|
+
nokogiri (1.6.6.2)
|
15
|
+
mini_portile (~> 0.6.0)
|
16
|
+
nokogumbo (1.4.1)
|
17
|
+
nokogiri
|
18
|
+
rake (0.9.2.2)
|
19
|
+
sanitize (4.0.0)
|
20
|
+
crass (~> 1.0.2)
|
21
|
+
nokogiri (>= 1.4.4)
|
22
|
+
nokogumbo (= 1.4.1)
|
23
|
+
|
24
|
+
PLATFORMS
|
25
|
+
ruby
|
26
|
+
|
27
|
+
DEPENDENCIES
|
28
|
+
bundler (~> 1.5)
|
29
|
+
evernote-jeeves!
|
30
|
+
rake
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Fran Fabrizio
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
evernote-jeeves
|
2
|
+
===============
|
3
|
+
|
4
|
+
This command-line Ruby script searches for a given search string S in all notes updated in the last N days,
|
5
|
+
and displays all lines containing that search string, along with some useful note and folder context metadata.
|
6
|
+
|
7
|
+
Use Case
|
8
|
+
========
|
9
|
+
|
10
|
+
I use Evernote all day long at work, sometimes making a dozen notes in a day. I've developed a TODO habit,
|
11
|
+
where I'll write something like this in a note:
|
12
|
+
|
13
|
+
```
|
14
|
+
TODO Follow-up with Bob regarding the FY15 budgets
|
15
|
+
```
|
16
|
+
|
17
|
+
Problem is, at the end of the day or week, I'll have to hunt back through all of my notes to find my TODOs.
|
18
|
+
So I wrote a script to help.
|
19
|
+
|
20
|
+
Usage
|
21
|
+
=====
|
22
|
+
|
23
|
+
```
|
24
|
+
Usage: jeeves.rb [options]
|
25
|
+
-v, --verbose Run verbosely
|
26
|
+
-s, --search s Search string to look for in notes.
|
27
|
+
-i, --ignorecase Search case-insensitively
|
28
|
+
-d, --days N Number of days in the past to search.
|
29
|
+
-h, --help Show this message
|
30
|
+
|
31
|
+
$ ruby jeeves.rb -d 7 -s TODO
|
32
|
+
Budget Meeting (06/09/14, Finance)
|
33
|
+
TODO Follow-up with Bob regarding the FY15 budgets
|
34
|
+
|
35
|
+
Team Dev Meeting (06/05/14, IT)
|
36
|
+
TODO Renew RubyMine licenses
|
37
|
+
TODO Check on RailsConf expense reports
|
38
|
+
|
39
|
+
1:1 with James (06/04/14, Supervision)
|
40
|
+
TODO Establish backup on-call plan during James' vacation
|
41
|
+
```
|
42
|
+
|
43
|
+
Known Issues
|
44
|
+
============
|
45
|
+
|
46
|
+
Software not generally ready for distribution (no Gemfile, no VERSION, etc... etc...)
|
47
|
+
|
48
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/bin/jeeves
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'evernote/jeeves/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "evernote-jeeves"
|
8
|
+
spec.version = Evernote::Jeeves::VERSION
|
9
|
+
spec.authors = ["Fran Fabrizio"]
|
10
|
+
spec.email = ["franfabrizio@gmail.com"]
|
11
|
+
spec.summary = %q{Harvests lines with specific keywords from your Evernote notes.}
|
12
|
+
spec.description = %q{}
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.5"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
|
24
|
+
spec.add_runtime_dependency "evernote-thrift"
|
25
|
+
spec.add_runtime_dependency "sanitize"
|
26
|
+
|
27
|
+
end
|
@@ -0,0 +1,160 @@
|
|
1
|
+
require "evernote/jeeves/version"
|
2
|
+
|
3
|
+
require 'evernote-thrift'
|
4
|
+
require 'digest/md5'
|
5
|
+
require 'pp'
|
6
|
+
require 'yaml'
|
7
|
+
require 'sanitize'
|
8
|
+
require 'optparse'
|
9
|
+
require 'ostruct'
|
10
|
+
|
11
|
+
module Evernote
|
12
|
+
module Jeeves
|
13
|
+
class JeevesOptionsParser
|
14
|
+
|
15
|
+
def self.parse(args)
|
16
|
+
options = OpenStruct.new
|
17
|
+
#defaults
|
18
|
+
options.verbose = FALSE
|
19
|
+
options.search = 'TODO'
|
20
|
+
options.ignorecase = FALSE
|
21
|
+
options.days = 7
|
22
|
+
|
23
|
+
opts_parser = OptionParser.new do |opts|
|
24
|
+
opts.banner = "Usage: jeeves.rb [options]"
|
25
|
+
|
26
|
+
opts.on("-v", "--verbose", "Run verbosely") do |v|
|
27
|
+
options.verbose = v
|
28
|
+
end
|
29
|
+
|
30
|
+
opts.on("-s", "--search s", String, "Search string to look for in notes.") do |s|
|
31
|
+
options.search = s
|
32
|
+
end
|
33
|
+
|
34
|
+
opts.on("-i", "--ignorecase", "Search case-insensitively") do |i|
|
35
|
+
options.ignorecase = Regexp::IGNORECASE
|
36
|
+
end
|
37
|
+
|
38
|
+
opts.on("-d", "--days N", Integer, "Number of days in the past to search.") do |d|
|
39
|
+
options.days = d
|
40
|
+
end
|
41
|
+
|
42
|
+
opts.on_tail("-h", "--help", "Show this message") do
|
43
|
+
puts opts
|
44
|
+
exit
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
opts_parser.parse!(args)
|
49
|
+
options
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
class JeevesRunner
|
54
|
+
def run
|
55
|
+
options = JeevesOptionsParser.parse(ARGV)
|
56
|
+
|
57
|
+
# get the authToken from config
|
58
|
+
config = YAML.load_file(File.join(ENV['HOME'], '/.jeeves/config.yml'))
|
59
|
+
authToken = config["config"]["authToken"]
|
60
|
+
|
61
|
+
# Since this app only accesses your own Evernote account, we can use a developer token
|
62
|
+
# that allows you to access your own Evernote account and skip OAuth authentication.
|
63
|
+
# To get a developer token, visit https://sandbox.evernote.com/api/DeveloperToken.action
|
64
|
+
|
65
|
+
if authToken == "your developer token"
|
66
|
+
puts "Please fill in your developer token"
|
67
|
+
puts "To get a developer token, visit https://sandbox.evernote.com/api/DeveloperToken.action"
|
68
|
+
exit(1)
|
69
|
+
end
|
70
|
+
|
71
|
+
# Initial development can be performed on Evernote's sandbox server. It requires a separate
|
72
|
+
# account and authToken. To switch to using the sandbox server, change "www.evernote.com" to
|
73
|
+
# "sandbox.evernote.com" and replace your developer token above with a sandbox token.
|
74
|
+
#evernoteHost = "sandbox.evernote.com"
|
75
|
+
evernoteHost = "www.evernote.com"
|
76
|
+
userStoreUrl = "https://#{evernoteHost}/edam/user"
|
77
|
+
|
78
|
+
userStoreTransport = Thrift::HTTPClientTransport.new(userStoreUrl)
|
79
|
+
userStoreProtocol = Thrift::BinaryProtocol.new(userStoreTransport)
|
80
|
+
userStore = Evernote::EDAM::UserStore::UserStore::Client.new(userStoreProtocol)
|
81
|
+
|
82
|
+
# Verify your Evernote gem is up to date
|
83
|
+
versionOK = userStore.checkVersion("Evernote EDAM (Ruby)",
|
84
|
+
Evernote::EDAM::UserStore::EDAM_VERSION_MAJOR,
|
85
|
+
Evernote::EDAM::UserStore::EDAM_VERSION_MINOR)
|
86
|
+
raise RuntimeError, "API version out of date" unless versionOK
|
87
|
+
|
88
|
+
# Get the URL used to interact with the contents of the user's account
|
89
|
+
# When your application authenticates using OAuth, the NoteStore URL will
|
90
|
+
# be returned along with the auth token in the final OAuth request.
|
91
|
+
# In that case, you don't need to make this call.
|
92
|
+
begin
|
93
|
+
noteStoreUrl = userStore.getNoteStoreUrl(authToken)
|
94
|
+
rescue Evernote::EDAM::Error::EDAMUserException => e
|
95
|
+
pp e
|
96
|
+
#puts e.getErrorCode()
|
97
|
+
end
|
98
|
+
|
99
|
+
noteStoreTransport = Thrift::HTTPClientTransport.new(noteStoreUrl)
|
100
|
+
noteStoreProtocol = Thrift::BinaryProtocol.new(noteStoreTransport)
|
101
|
+
noteStore = Evernote::EDAM::NoteStore::NoteStore::Client.new(noteStoreProtocol)
|
102
|
+
|
103
|
+
# search notes
|
104
|
+
noteFilter = Evernote::EDAM::NoteStore::NoteFilter.new
|
105
|
+
# 2 == sort results by updated
|
106
|
+
noteFilter.order = 2
|
107
|
+
# newest first
|
108
|
+
noteFilter.ascending = FALSE
|
109
|
+
noteFilter.words = "updated:day-#{options.days} #{options.search}"
|
110
|
+
|
111
|
+
# We want our search results to return title, notebook GUID, and updated date
|
112
|
+
spec = Evernote::EDAM::NoteStore::NotesMetadataResultSpec.new
|
113
|
+
spec.includeTitle = true
|
114
|
+
spec.includeNotebookGuid = true
|
115
|
+
spec.includeUpdated = true
|
116
|
+
|
117
|
+
# we limit to 100 results to avoid craziness
|
118
|
+
noteList = noteStore.findNotesMetadata(authToken,noteFilter,0,100, spec)
|
119
|
+
|
120
|
+
displayedNotes = Array.new
|
121
|
+
searchPattern = Regexp.new(options.search, options.ignorecase)
|
122
|
+
|
123
|
+
noteList.notes.each do |note|
|
124
|
+
# retrieve the note - just the contents, don't need other resources
|
125
|
+
doc = noteStore.getNote(authToken, note.guid, true, false, false, false).content
|
126
|
+
noteMatches = false
|
127
|
+
matchingLines = ""
|
128
|
+
# look for the search string in this note's content, line-by-line
|
129
|
+
doc.lines.each do |line|
|
130
|
+
if line =~ searchPattern
|
131
|
+
noteMatches = true
|
132
|
+
# indentation hack
|
133
|
+
matchingLines << " #{Sanitize.clean(line).strip}\n"
|
134
|
+
end
|
135
|
+
end
|
136
|
+
if noteMatches
|
137
|
+
# display note metadata along with matching lines
|
138
|
+
displayedNotes << "#{note.title} (#{Time.at(note.updated/1000).strftime("%m/%d/%y")}, " +
|
139
|
+
"#{noteStore.getNotebook(authToken, note.notebookGuid).name})\n#{matchingLines}\n"
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
# time to display the results
|
144
|
+
if options.verbose
|
145
|
+
puts "There are #{displayedNotes.count} matching notes.\n\n"
|
146
|
+
end
|
147
|
+
|
148
|
+
displayedNotes.each do |text|
|
149
|
+
puts text
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
if __FILE__ == $0
|
157
|
+
ej = Evernote::Jeeves::JeevesRunner.new
|
158
|
+
ej.run
|
159
|
+
end
|
160
|
+
|
Binary file
|
data/version
ADDED
File without changes
|
metadata
ADDED
@@ -0,0 +1,114 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: evernote-jeeves
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Fran Fabrizio
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-09-12 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.5'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.5'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: evernote-thrift
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: sanitize
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
description: ''
|
70
|
+
email:
|
71
|
+
- franfabrizio@gmail.com
|
72
|
+
executables:
|
73
|
+
- jeeves
|
74
|
+
extensions: []
|
75
|
+
extra_rdoc_files: []
|
76
|
+
files:
|
77
|
+
- ".gitignore"
|
78
|
+
- Gemfile
|
79
|
+
- Gemfile.lock
|
80
|
+
- LICENSE.txt
|
81
|
+
- README.md
|
82
|
+
- Rakefile
|
83
|
+
- bin/jeeves
|
84
|
+
- config/config.example.yml
|
85
|
+
- evernote-jeeves.gemspec
|
86
|
+
- lib/evernote/jeeves.rb
|
87
|
+
- lib/evernote/jeeves/version.rb
|
88
|
+
- pkg/evernote-jeeves-0.0.1.gem
|
89
|
+
- version
|
90
|
+
homepage: ''
|
91
|
+
licenses:
|
92
|
+
- MIT
|
93
|
+
metadata: {}
|
94
|
+
post_install_message:
|
95
|
+
rdoc_options: []
|
96
|
+
require_paths:
|
97
|
+
- lib
|
98
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - ">="
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '0'
|
103
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
104
|
+
requirements:
|
105
|
+
- - ">="
|
106
|
+
- !ruby/object:Gem::Version
|
107
|
+
version: '0'
|
108
|
+
requirements: []
|
109
|
+
rubyforge_project:
|
110
|
+
rubygems_version: 2.4.6
|
111
|
+
signing_key:
|
112
|
+
specification_version: 4
|
113
|
+
summary: Harvests lines with specific keywords from your Evernote notes.
|
114
|
+
test_files: []
|