enwrite 0.2.0
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.
- checksums.yaml +7 -0
- data/.document +5 -0
- data/Gemfile +18 -0
- data/Gemfile.lock +69 -0
- data/LICENSE +22 -0
- data/LICENSE.txt +20 -0
- data/README.md +90 -0
- data/Rakefile +56 -0
- data/bin/enwrite +11 -0
- data/lib/enml-utils.rb +196 -0
- data/lib/enwrite.rb +299 -0
- data/lib/evernote-utils.rb +234 -0
- data/lib/filters.rb +64 -0
- data/lib/output.rb +9 -0
- data/lib/output/hugo.rb +236 -0
- data/lib/util.rb +44 -0
- data/test/helper.rb +34 -0
- data/test/test_enwrite.rb +7 -0
- metadata +179 -0
data/lib/enwrite.rb
ADDED
@@ -0,0 +1,299 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
#
|
4
|
+
# enwrite - power a web site using Evernote
|
5
|
+
#
|
6
|
+
# Diego Zamboni, March 2015
|
7
|
+
# Time-stamp: <2015-04-30 13:39:37 diego>
|
8
|
+
|
9
|
+
require 'rubygems'
|
10
|
+
require 'bundler/setup'
|
11
|
+
|
12
|
+
require "digest/md5"
|
13
|
+
require 'evernote-thrift'
|
14
|
+
require 'evernote-utils'
|
15
|
+
require "optparse"
|
16
|
+
require "ostruct"
|
17
|
+
require 'util'
|
18
|
+
require 'yaml'
|
19
|
+
require 'deep_merge'
|
20
|
+
|
21
|
+
class Enwrite
|
22
|
+
PLUGINS = %w[hugo]
|
23
|
+
module Version
|
24
|
+
MAJOR = 0
|
25
|
+
MINOR = 2
|
26
|
+
PATCH = 0
|
27
|
+
|
28
|
+
STRING = [MAJOR, MINOR, PATCH].compact.join('.')
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.run
|
32
|
+
|
33
|
+
options = OpenStruct.new
|
34
|
+
options.removetags = []
|
35
|
+
options.verbose = false
|
36
|
+
options.debug = false
|
37
|
+
options.outputplugin = 'hugo'
|
38
|
+
options.configtag = '_enwrite_config'
|
39
|
+
options.filestagprefix = '_enwrite_files'
|
40
|
+
|
41
|
+
opts = OptionParser.new do |opts|
|
42
|
+
def opts.version_string
|
43
|
+
"Enwrite v#{Enwrite::Version::STRING}"
|
44
|
+
end
|
45
|
+
|
46
|
+
opts.banner = "#{opts.version_string}\n\nUsage: #{$0} [options] (at least one of -n or -s has to be specified)"
|
47
|
+
|
48
|
+
def opts.show_usage
|
49
|
+
puts self
|
50
|
+
exit
|
51
|
+
end
|
52
|
+
|
53
|
+
def opts.show_version
|
54
|
+
puts version_string
|
55
|
+
exit
|
56
|
+
end
|
57
|
+
|
58
|
+
opts.separator "\nSearch options:"
|
59
|
+
opts.on("-n", "--notebook NOTEBOOK",
|
60
|
+
"Process notes from specified notebook.") do |notebook|
|
61
|
+
options.notebook = notebook
|
62
|
+
end
|
63
|
+
opts.on("-t", "--tag TAG",
|
64
|
+
"Process only notes that have this tag",
|
65
|
+
"within the given notebook.") do |tag|
|
66
|
+
options.tag = tag
|
67
|
+
end
|
68
|
+
opts.on("--remove-tags [t1,t2,t3]", Array,
|
69
|
+
"List of tags to remove from output posts.",
|
70
|
+
"If no argument given, defaults to --tag.") do |removetags|
|
71
|
+
options.removetags = removetags || [options.tag]
|
72
|
+
end
|
73
|
+
opts.on("-s", "--search SEARCHEXP",
|
74
|
+
"Process notes that match given search",
|
75
|
+
"expression. If specified, --notebook",
|
76
|
+
"and --tag are ignored.") do |searchexp|
|
77
|
+
options.searchexp = searchexp
|
78
|
+
options.tag = nil
|
79
|
+
options.notebook = nil
|
80
|
+
end
|
81
|
+
opts.separator 'Output options:'
|
82
|
+
opts.on("-p", "--output-plugin PLUGIN", PLUGINS,
|
83
|
+
"Output plugin to use (Valid values: #{PLUGINS.join(', ')})") do |plugin|
|
84
|
+
options.outputplugin = plugin
|
85
|
+
end
|
86
|
+
opts.on("-o", "--output-dir OUTDIR",
|
87
|
+
"Base dir of hugo output installation") do |outdir|
|
88
|
+
options.outdir = outdir
|
89
|
+
end
|
90
|
+
opts.on("--rebuild-all",
|
91
|
+
"Process all notes that match the given",
|
92
|
+
"conditions (normally only updated notes",
|
93
|
+
"are processed)") { options.rebuild_all = true }
|
94
|
+
opts.separator 'Other options:'
|
95
|
+
opts.on("--auth [TOKEN]",
|
96
|
+
"Force Evernote reauthentication (will",
|
97
|
+
"happen automatically if needed). Use",
|
98
|
+
"TOKEN if given, otherwise get one",
|
99
|
+
"interactively.") do |forceauth|
|
100
|
+
options.forceauth = true
|
101
|
+
options.authtoken = forceauth
|
102
|
+
end
|
103
|
+
opts.on("--config-tag TAG",
|
104
|
+
"Specify tag to determine config notes",
|
105
|
+
"(default: #{options.configtag})") { |conftag|
|
106
|
+
options.configtag = conftag
|
107
|
+
}
|
108
|
+
opts.on_tail("-v", "--verbose", "Verbose mode") { options.verbose=true }
|
109
|
+
opts.on_tail("-d", "--debug", "Debug output mode") {
|
110
|
+
options.debug=true
|
111
|
+
options.verbose=true
|
112
|
+
}
|
113
|
+
opts.on_tail("--version", "Show version") { opts.show_version }
|
114
|
+
opts.on_tail("-h", "--help", "Shows this help message") { opts.show_usage }
|
115
|
+
end
|
116
|
+
|
117
|
+
opts.parse!
|
118
|
+
|
119
|
+
begin
|
120
|
+
eval "require 'output/#{options.outputplugin}'"
|
121
|
+
rescue LoadError
|
122
|
+
error "There was an error loading output module '#{plugin}': #{e.to_s}"
|
123
|
+
exit 1
|
124
|
+
end
|
125
|
+
|
126
|
+
$enwrite_verbose = options.verbose
|
127
|
+
$enwrite_debug = options.debug
|
128
|
+
|
129
|
+
verbose("Options: " + options.to_s)
|
130
|
+
|
131
|
+
if not (options.notebook or options.searchexp or options.forceauth)
|
132
|
+
error "You have to specify at least one of --notebook, --search or --auth"
|
133
|
+
exit(1)
|
134
|
+
end
|
135
|
+
exps = [ options.searchexp ? options.searchexp : nil,
|
136
|
+
options.notebook ? "notebook:#{options.notebook}" : nil,
|
137
|
+
options.tag ? "tag:#{options.tag}" : nil,
|
138
|
+
].reject(&:nil?)
|
139
|
+
searchexp = exps.join(' ')
|
140
|
+
|
141
|
+
verbose "Output dir: #{options.outdir}"
|
142
|
+
verbose "Search expression: #{searchexp}"
|
143
|
+
|
144
|
+
begin
|
145
|
+
|
146
|
+
# Initialize Evernote access
|
147
|
+
Evernote_utils.init(options.forceauth, options.authtoken)
|
148
|
+
|
149
|
+
if not searchexp # Only --auth was specified
|
150
|
+
exit 0
|
151
|
+
end
|
152
|
+
|
153
|
+
updatecount_index = "updatecount_#{searchexp}"
|
154
|
+
latestUpdateCount = config(updatecount_index, 0)
|
155
|
+
if options.rebuild_all
|
156
|
+
msg "Processing ALL notes (--rebuild-all)."
|
157
|
+
latestUpdateCount = 0
|
158
|
+
end
|
159
|
+
|
160
|
+
verbose "Latest stored update count for #{searchexp}: #{latestUpdateCount}"
|
161
|
+
|
162
|
+
currentState = Evernote_utils.noteStore.getSyncState(Evernote_utils.authToken)
|
163
|
+
currentUpdateCount = currentState.updateCount
|
164
|
+
|
165
|
+
verbose "Current update count for the account: #{currentUpdateCount}"
|
166
|
+
|
167
|
+
if (currentUpdateCount > latestUpdateCount)
|
168
|
+
msg "Reading #{options.rebuild_all ? 'all' : 'updated'} notes that match #{searchexp}"
|
169
|
+
|
170
|
+
filter = Evernote::EDAM::NoteStore::NoteFilter.new
|
171
|
+
filter.words = searchexp
|
172
|
+
filter.order = Evernote::EDAM::Type::NoteSortOrder::UPDATE_SEQUENCE_NUMBER
|
173
|
+
filter.ascending = false
|
174
|
+
|
175
|
+
spec = Evernote::EDAM::NoteStore::NotesMetadataResultSpec.new
|
176
|
+
spec.includeTitle = true
|
177
|
+
spec.includeCreated = true
|
178
|
+
spec.includeTagGuids = true
|
179
|
+
spec.includeContentLength = true
|
180
|
+
spec.includeUpdateSequenceNum = true
|
181
|
+
spec.includeDeleted = true
|
182
|
+
|
183
|
+
results = Evernote_utils.noteStore.findNotesMetadata(Evernote_utils.authToken,
|
184
|
+
filter,
|
185
|
+
0,
|
186
|
+
Evernote::EDAM::Limits::EDAM_USER_NOTES_MAX,
|
187
|
+
spec)
|
188
|
+
|
189
|
+
# Get also deleted notes so we can remove from the blog
|
190
|
+
filter.inactive = true
|
191
|
+
delresults = Evernote_utils.noteStore.findNotesMetadata(Evernote_utils.authToken,
|
192
|
+
filter,
|
193
|
+
0,
|
194
|
+
Evernote::EDAM::Limits::EDAM_USER_NOTES_MAX,
|
195
|
+
spec)
|
196
|
+
|
197
|
+
# Go through the list looking for config notes, parse them and remove
|
198
|
+
# them from the list
|
199
|
+
enwriteconfig = { 'hugo' => {
|
200
|
+
'base_dir' => options.outdir,
|
201
|
+
'rebuild_all' => options.rebuild_all,
|
202
|
+
},
|
203
|
+
}
|
204
|
+
|
205
|
+
if Evernote_utils.tags.include?(options.configtag)
|
206
|
+
config_tag_guid = Evernote_utils.tags[options.configtag].guid
|
207
|
+
results.notes.select { |note|
|
208
|
+
note.tagGuids.include?(config_tag_guid)
|
209
|
+
}.each { |confignotemd|
|
210
|
+
msg "Found config note '#{confignotemd.title}'"
|
211
|
+
confignote = Evernote_utils.getWholeNote(confignotemd)
|
212
|
+
enml = ENML_utils.new(confignote.content)
|
213
|
+
configtext = enml.to_text
|
214
|
+
debug " Config note text: '#{configtext}'"
|
215
|
+
configyaml = YAML.load(configtext)
|
216
|
+
debug " Config note YAML: #{configyaml}"
|
217
|
+
enwriteconfig.deep_merge!(configyaml)
|
218
|
+
debug " enwriteconfig = #{enwriteconfig}"
|
219
|
+
results.notes.delete(confignotemd)
|
220
|
+
results.totalNotes -= 1
|
221
|
+
}
|
222
|
+
end
|
223
|
+
verbose "Final enwrite config: #{enwriteconfig}"
|
224
|
+
|
225
|
+
files_tag = "#{options.filestagprefix}_#{options.outputplugin}"
|
226
|
+
|
227
|
+
if Evernote_utils.tags.include?(files_tag)
|
228
|
+
files_tag_guid = Evernote_utils.tags[files_tag].guid
|
229
|
+
results.notes.select { |note|
|
230
|
+
note.tagGuids.include?(files_tag_guid) &&
|
231
|
+
note.updateSequenceNum > latestUpdateCount
|
232
|
+
}.each { |filesnotemd|
|
233
|
+
msg "Found files note '#{filesnotemd.title}'"
|
234
|
+
filesnote = Evernote_utils.getWholeNote(filesnotemd)
|
235
|
+
enml = ENML_utils.new(filesnote.content, filesnote.resources)
|
236
|
+
files = enml.resource_files
|
237
|
+
Dir.chdir("#{options.outdir}")
|
238
|
+
files.each do |file|
|
239
|
+
case
|
240
|
+
when file[:basename] =~ /\.tar.gz$/
|
241
|
+
f = Tempfile.new('enwrite')
|
242
|
+
begin
|
243
|
+
verbose " Saving file #{file[:basename]} to #{f.path}"
|
244
|
+
f.write(file[:data])
|
245
|
+
f.close
|
246
|
+
verbose " Unpacking file #{f.path} with tar"
|
247
|
+
ok = system("tar zxf #{f.path}")
|
248
|
+
unless ok
|
249
|
+
error " An error occurred when unpacking #{f.path}"
|
250
|
+
end
|
251
|
+
ensure
|
252
|
+
f.close
|
253
|
+
f.unlink
|
254
|
+
end
|
255
|
+
else
|
256
|
+
open("#{options.outdir}/#{file[:basename]}", "w") do |f|
|
257
|
+
verbose " Saving file #{f.path}"
|
258
|
+
f.write(file[:data])
|
259
|
+
end
|
260
|
+
end
|
261
|
+
end
|
262
|
+
results.notes.delete(filesnotemd)
|
263
|
+
results.totalNotes -= 1
|
264
|
+
}
|
265
|
+
end
|
266
|
+
|
267
|
+
debug "Evaluating: #{options.outputplugin.capitalize}.new(enwriteconfig[options.outputplugin])"
|
268
|
+
writer = eval "#{options.outputplugin.capitalize}.new(enwriteconfig[options.outputplugin])"
|
269
|
+
|
270
|
+
(results.notes + delresults.notes).select {
|
271
|
+
|note| note.updateSequenceNum > latestUpdateCount
|
272
|
+
}.sort_by {
|
273
|
+
|note| note.updateSequenceNum
|
274
|
+
}.each do |metadata|
|
275
|
+
verbose "######################################################################"
|
276
|
+
note = Evernote_utils.getWholeNote(metadata)
|
277
|
+
note.tagNames = note.tagNames - options.removetags
|
278
|
+
# This either creates or deletes posts as appropriate
|
279
|
+
writer.output_note(note)
|
280
|
+
end
|
281
|
+
# Persist the latest updatecount for next time
|
282
|
+
setconfig(updatecount_index, currentUpdateCount)
|
283
|
+
|
284
|
+
exit 0
|
285
|
+
else
|
286
|
+
msg "No updated notes that match #{searchexp}"
|
287
|
+
exit 1
|
288
|
+
end
|
289
|
+
rescue Evernote::EDAM::Error::EDAMUserException => e
|
290
|
+
#the exceptions that come back from Evernote are hard to read, but really important to keep track of
|
291
|
+
msg = "Caught an exception from Evernote trying to create a note. #{Evernote_utils.translate_error(e)}"
|
292
|
+
raise msg
|
293
|
+
rescue Evernote::EDAM::Error::EDAMSystemException => e
|
294
|
+
#the exceptions that come back from Evernote are hard to read, but really important to keep track of
|
295
|
+
msg = "Caught an exception from Evernote trying to create a note. #{Evernote_utils.translate_error(e)}"
|
296
|
+
raise msg
|
297
|
+
end
|
298
|
+
end
|
299
|
+
end
|
@@ -0,0 +1,234 @@
|
|
1
|
+
#
|
2
|
+
# Evernote access utilities
|
3
|
+
#
|
4
|
+
# Diego Zamboni, March 2015
|
5
|
+
# Time-stamp: <2015-04-16 23:09:37 diego>
|
6
|
+
|
7
|
+
# Load libraries required by the Evernote OAuth
|
8
|
+
require 'oauth'
|
9
|
+
require 'oauth/consumer'
|
10
|
+
|
11
|
+
# Load Thrift & Evernote Ruby libraries
|
12
|
+
require "evernote_oauth"
|
13
|
+
|
14
|
+
class Evernote_utils
|
15
|
+
|
16
|
+
# Client credentials for enwrite
|
17
|
+
OAUTH_CONSUMER_KEY = "zzamboni-2648"
|
18
|
+
OAUTH_CONSUMER_SECRET = "05f988c37b5e8c68"
|
19
|
+
|
20
|
+
# Connect to Sandbox server?
|
21
|
+
SANDBOX = false
|
22
|
+
|
23
|
+
# Environment variable in which to look for the token
|
24
|
+
ENVVAR = 'ENWRITE_AUTH_TOKEN'
|
25
|
+
|
26
|
+
@@authToken = nil
|
27
|
+
@@userStore = nil
|
28
|
+
@@noteStore = nil
|
29
|
+
@@notebooks = nil
|
30
|
+
@@tags = nil
|
31
|
+
@@forceAuth = false
|
32
|
+
|
33
|
+
def self.interactiveGetToken
|
34
|
+
callback_url = "http://zzamboni.org/enwrite-callback.html"
|
35
|
+
client = EvernoteOAuth::Client.new(token: nil, consumer_key: OAUTH_CONSUMER_KEY, consumer_secret: OAUTH_CONSUMER_SECRET, sandbox: SANDBOX)
|
36
|
+
request_token = client.request_token(:oauth_callback => callback_url)
|
37
|
+
authorize_url = request_token.authorize_url
|
38
|
+
|
39
|
+
puts("Welcome to enwrite's Evernote authentication.
|
40
|
+
|
41
|
+
Please open the following URL:
|
42
|
+
#{authorize_url}
|
43
|
+
|
44
|
+
Once you authenticate you will be redirected to
|
45
|
+
a page in the zzamboni.org domain that will show you an authentication verifier
|
46
|
+
token. Please enter that token now.")
|
47
|
+
print("> ")
|
48
|
+
$stdout.flush
|
49
|
+
oauth_verifier = gets.chomp
|
50
|
+
|
51
|
+
access_token = request_token.get_access_token(:oauth_verifier => oauth_verifier)
|
52
|
+
|
53
|
+
puts("Thank you! Your access token is the following string:
|
54
|
+
#{access_token.token}
|
55
|
+
|
56
|
+
I can store the token for you in the config file (#{config_file}),
|
57
|
+
then enwrite will use it automatically in the future.
|
58
|
+
")
|
59
|
+
print "Would you like me to do that for you now (Y/n)? "
|
60
|
+
$stdout.flush
|
61
|
+
yesno = gets.chomp
|
62
|
+
if yesno =~ /^[yY]/
|
63
|
+
setconfig(:evernote_auth_token, access_token.token)
|
64
|
+
puts "Token stored."
|
65
|
+
else
|
66
|
+
puts "OK, I won't store the token, just use it for now.
|
67
|
+
|
68
|
+
You can also store it in the ENWRITE_AUTH_TOKEN environment variable."
|
69
|
+
end
|
70
|
+
# Cancel force mode after we've gotten the token
|
71
|
+
@@forceAuth = false
|
72
|
+
|
73
|
+
return access_token.token
|
74
|
+
end
|
75
|
+
|
76
|
+
def self.getToken
|
77
|
+
if @@forceAuth
|
78
|
+
return self.interactiveGetToken
|
79
|
+
elsif not ENV[ENVVAR].nil?
|
80
|
+
return ENV[ENVVAR]
|
81
|
+
elsif not config(:evernote_auth_token).nil?
|
82
|
+
return config(:evernote_auth_token)
|
83
|
+
else
|
84
|
+
return self.interactiveGetToken
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def self.authToken
|
89
|
+
if @@authToken == nil || @@forceAuth
|
90
|
+
@@authToken = self.getToken
|
91
|
+
end
|
92
|
+
return @@authToken
|
93
|
+
end
|
94
|
+
|
95
|
+
def self.userStore
|
96
|
+
if @@userStore == nil
|
97
|
+
# Initial development is performed on our sandbox server. To use the production
|
98
|
+
# service, change "sandbox.evernote.com" to "www.evernote.com" and replace your
|
99
|
+
# developer token above with a token from
|
100
|
+
# https://www.evernote.com/api/DeveloperToken.action
|
101
|
+
evernoteHost = SANDBOX ? "sandbox.evernote.com" : "www.evernote.com"
|
102
|
+
userStoreUrl = "https://#{evernoteHost}/edam/user"
|
103
|
+
|
104
|
+
userStoreTransport = Thrift::HTTPClientTransport.new(userStoreUrl)
|
105
|
+
userStoreProtocol = Thrift::BinaryProtocol.new(userStoreTransport)
|
106
|
+
@@userStore = Evernote::EDAM::UserStore::UserStore::Client.new(userStoreProtocol)
|
107
|
+
end
|
108
|
+
return @@userStore
|
109
|
+
end
|
110
|
+
|
111
|
+
def self.checkVersion
|
112
|
+
versionOK = self.userStore.checkVersion("enwrite",
|
113
|
+
Evernote::EDAM::UserStore::EDAM_VERSION_MAJOR,
|
114
|
+
Evernote::EDAM::UserStore::EDAM_VERSION_MINOR)
|
115
|
+
verbose "Is my Evernote API version up to date? #{versionOK}"
|
116
|
+
unless versionOK
|
117
|
+
error "Please update the Evernote Ruby libraries - they are not up to date."
|
118
|
+
exit(1)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def self.noteStore
|
123
|
+
if @@noteStore == nil
|
124
|
+
# Get the URL used to interact with the contents of the user's account
|
125
|
+
# When your application authenticates using OAuth, the NoteStore URL will
|
126
|
+
# be returned along with the auth token in the final OAuth request.
|
127
|
+
# In that case, you don't need to make this call.
|
128
|
+
noteStoreUrl = self.userStore.getNoteStoreUrl(self.authToken)
|
129
|
+
|
130
|
+
noteStoreTransport = Thrift::HTTPClientTransport.new(noteStoreUrl)
|
131
|
+
noteStoreProtocol = Thrift::BinaryProtocol.new(noteStoreTransport)
|
132
|
+
@@noteStore = Evernote::EDAM::NoteStore::NoteStore::Client.new(noteStoreProtocol)
|
133
|
+
end
|
134
|
+
return @@noteStore
|
135
|
+
end
|
136
|
+
|
137
|
+
def self.notebooks(force=false)
|
138
|
+
if (@@notebooks == nil) or force
|
139
|
+
# List all of the notebooks in the user's account
|
140
|
+
@@notebooks = self.noteStore.listNotebooks(self.authToken)
|
141
|
+
verbose "Found #{notebooks.size} notebooks:"
|
142
|
+
defaultNotebook = notebooks.first
|
143
|
+
notebooks.each do |notebook|
|
144
|
+
verbose " * #{notebook.name}"
|
145
|
+
end
|
146
|
+
end
|
147
|
+
return @@notebooks
|
148
|
+
end
|
149
|
+
|
150
|
+
def self.tags(force=false)
|
151
|
+
if (@@tags == nil) or force
|
152
|
+
verbose "Reading all tags:"
|
153
|
+
|
154
|
+
# Get list of all tags, cache it for future use
|
155
|
+
taglist = self.noteStore.listTags(self.authToken)
|
156
|
+
# Create a hash for easier reference
|
157
|
+
@@tags = {}
|
158
|
+
tagstr = ""
|
159
|
+
for t in taglist
|
160
|
+
@@tags[t.guid] = t
|
161
|
+
@@tags[t.name] = t
|
162
|
+
tagstr += "#{t.name} "
|
163
|
+
end
|
164
|
+
verbose tagstr
|
165
|
+
end
|
166
|
+
return @@tags
|
167
|
+
end
|
168
|
+
|
169
|
+
def self.init(force=false, token=nil)
|
170
|
+
@@forceAuth = force
|
171
|
+
if not token.nil?
|
172
|
+
@@forceAuth = false
|
173
|
+
@@authToken = token
|
174
|
+
end
|
175
|
+
self.authToken
|
176
|
+
self.userStore
|
177
|
+
self.checkVersion
|
178
|
+
self.noteStore
|
179
|
+
|
180
|
+
self.notebooks
|
181
|
+
self.tags
|
182
|
+
end
|
183
|
+
|
184
|
+
def self.getWholeNote(metadata)
|
185
|
+
note = self.noteStore.getNote(self.authToken, metadata.guid, true, true, false, false)
|
186
|
+
note.tagNames = []
|
187
|
+
if metadata.tagGuids != nil
|
188
|
+
tags = Evernote_utils.tags
|
189
|
+
note.tagNames = metadata.tagGuids.map { |guid| tags[guid].name }
|
190
|
+
end
|
191
|
+
verbose "Tags: #{note.tagNames}"
|
192
|
+
return note
|
193
|
+
end
|
194
|
+
|
195
|
+
# From http://pollen.io/2012/12/creating-a-note-in-evernote-from-ruby/
|
196
|
+
# With changes to handle RATE_LIMIT_REACHED
|
197
|
+
def self.translate_error(e)
|
198
|
+
error_name = "unknown"
|
199
|
+
case e.errorCode
|
200
|
+
when Evernote::EDAM::Error::EDAMErrorCode::AUTH_EXPIRED
|
201
|
+
error_name = "AUTH_EXPIRED"
|
202
|
+
when Evernote::EDAM::Error::EDAMErrorCode::BAD_DATA_FORMAT
|
203
|
+
error_name = "BAD_DATA_FORMAT"
|
204
|
+
when Evernote::EDAM::Error::EDAMErrorCode::DATA_CONFLICT
|
205
|
+
error_name = "DATA_CONFLICT"
|
206
|
+
when Evernote::EDAM::Error::EDAMErrorCode::DATA_REQUIRED
|
207
|
+
error_name = "DATA_REQUIRED"
|
208
|
+
when Evernote::EDAM::Error::EDAMErrorCode::ENML_VALIDATION
|
209
|
+
error_name = "ENML_VALIDATION"
|
210
|
+
when Evernote::EDAM::Error::EDAMErrorCode::INTERNAL_ERROR
|
211
|
+
error_name = "INTERNAL_ERROR"
|
212
|
+
when Evernote::EDAM::Error::EDAMErrorCode::INVALID_AUTH
|
213
|
+
error_name = "INVALID_AUTH"
|
214
|
+
when Evernote::EDAM::Error::EDAMErrorCode::LIMIT_REACHED
|
215
|
+
error_name = "LIMIT_REACHED"
|
216
|
+
when Evernote::EDAM::Error::EDAMErrorCode::PERMISSION_DENIED
|
217
|
+
error_name = "PERMISSION_DENIED"
|
218
|
+
when Evernote::EDAM::Error::EDAMErrorCode::QUOTA_REACHED
|
219
|
+
error_name = "QUOTA_REACHED"
|
220
|
+
when Evernote::EDAM::Error::EDAMErrorCode::SHARD_UNAVAILABLE
|
221
|
+
error_name = "SHARD_UNAVAILABLE"
|
222
|
+
when Evernote::EDAM::Error::EDAMErrorCode::UNKNOWN
|
223
|
+
error_name = "UNKNOWN"
|
224
|
+
when Evernote::EDAM::Error::EDAMErrorCode::VALID_VALUES
|
225
|
+
error_name = "VALID_VALUES"
|
226
|
+
when Evernote::EDAM::Error::EDAMErrorCode::VALUE_MAP
|
227
|
+
error_name = "VALUE_MAP"
|
228
|
+
when Evernote::EDAM::Error::EDAMErrorCode::RATE_LIMIT_REACHED
|
229
|
+
error_name = "RATE_LIMIT_REACHED"
|
230
|
+
e.message = "Rate limit reached. Please retry in #{e.rateLimitDuration} seconds"
|
231
|
+
end
|
232
|
+
rv = "Error code was: #{error_name}[#{e.errorCode}] and parameter: [#{e.message}]"
|
233
|
+
end
|
234
|
+
end
|