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