Evernote应用开发中,文档格式不太方便…
为了某些邪恶的想法,我决定用evernote的API把所有note导入本地处理。结果今天的时间几乎都花在了这个上面…虽然最终成功的把文章导出,但是同时发现了个很严重的问题:原以为evernote用html/xml直接给抓取的网页编码。结果没成想,note扒下来之后才发现,人家evernote用的是自己的enml格式(就是把xml的x改成evernote缩写…)。于是乎,各种浏览器纷纷表示无能为力。上网查询,evernote的工程师不知到什么时候说的目前还没有开发服务器端的格式转换API…瞬间傻眼了。下面先写个总结:
说到evernote的app开发,首先可以参考官网的dev page。在开发页面中,有evernote的整体开发流程介绍:
注册api key,下载SDK,然后再在sandbox里面注册一个新账户。就可以开发啦~lol
把下载的SDK解压,然后运行EDAMTest.py,注意:EDAMTest.py代码中需要填入developer token(而不是api key…)。注册developer token的地址:https://sandbox.evernote.com/api/DeveloperToken.action
执行结束,得到正确结果:
<br />
fnl@fnl-OptiPlex-790:~/evernote-sdk-python/sample$ python EDAMTest.py<br />
Is my Evernote API version up to date? True</p>
<p>Found 1 notebooks:<br />
* zhaoweichen 的笔记本</p>
<p>Creating a new note in the default notebook</p>
<p>Successfully created a new note with GUID: 3f6e1c19-54bd-48b7-ba59-b16589c7c8bb<br />
随后,就可以参照evernote的API参考手册来编写APP了~最后,虽然贴做出来的代码并没有达到搞定HTML文档的效果,至少也可以把所有文档下载下来。就贴在最后吧。
<br />
import sys<br />
import hashlib<br />
import binascii<br />
import time<br />
import thrift.protocol.TBinaryProtocol as TBinaryProtocol<br />
import thrift.transport.THttpClient as THttpClient<br />
import evernote.edam.userstore.UserStore as UserStore<br />
import evernote.edam.userstore.constants as UserStoreConstants<br />
import evernote.edam.notestore.NoteStore as NoteStore<br />
import evernote.edam.type.ttypes as Types<br />
import evernote.edam.error.ttypes as Errors</p>
<p>authToken = "填写你的developer token~"<br />
evernoteHost = "sandbox.evernote.com"<br />
userStoreUri = "https://" + evernoteHost + "/edam/user"</p>
<p>userStoreHttpClient = THttpClient.THttpClient(userStoreUri)<br />
userStoreProtocol = TBinaryProtocol.TBinaryProtocol(userStoreHttpClient)<br />
userStore = UserStore.Client(userStoreProtocol)</p>
<p>versionOK = userStore.checkVersion("Evernote EDAMTest (Python)",<br />
UserStoreConstants.EDAM_VERSION_MAJOR,<br />
UserStoreConstants.EDAM_VERSION_MINOR)<br />
print "Is my Evernote API version up to date? ", str(versionOK)<br />
print ""<br />
if not versionOK:<br />
exit(1)</p>
<p>noteStoreUrl = userStore.getNoteStoreUrl(authToken)<br />
noteStoreHttpClient = THttpClient.THttpClient(noteStoreUrl)<br />
noteStoreProtocol = TBinaryProtocol.TBinaryProtocol(noteStoreHttpClient)<br />
noteStore = NoteStore.Client(noteStoreProtocol)</p>
<p># List all of the notebooks in the user's account<br />
notebooks = noteStore.listNotebooks(authToken)<br />
print "Found ", len(notebooks), " notebooks:"<br />
for notebook in notebooks:<br />
print " * ", notebook.name<br />
print " notebook: ",notebook<br />
print " guid : ",notebook.guid</p>
<p>print "another try"</p>
<p>filter = NoteStore.NoteFilter()<br />
filter.notebookGuid = notebook.guid<br />
noteList = noteStore.findNotes(authToken,filter,0,10) #only matadata<br />
for n in noteList.notes:<br />
print n.title, n.guid<br />
content = noteStore.getNote(authToken, n.guid, True, False, False, False)<br />
fileHandle = open ( n.title + '.enml', 'w' )<br />
fileHandle.write ( content.content )<br />
fileHandle.close()<br />
其实,enml格式的问题也不是没有解决方法啦~就是会比较曲线:用evernote的邮件转发API转发至邮箱,然后再从邮箱里面抓取HTML代码…同样的,这么做是需要python支持IAMP邮箱登录等功能。好在有牛逼闪闪的库文件在。废话不多说,直接上代码~
<br />
import imaplib<br />
import email<br />
import StringIO</p>
<p>gmail_user = 'your email address'<br />
gmail_pass = 'your password'<br />
M = imaplib.IMAP4_SSL('imap.gmail.com')<br />
M.login(gmail_user, gmail_pass)<br />
M.select()<br />
fileHandle = open ( 'subject.html', 'a' )<br />
typ, data = M.search(None, 'ALL')<br />
for num in data[0].split():<br />
typ, data = M.fetch(num, '(RFC822)')<br />
tempMessage = StringIO.StringIO(data[0][1])<br />
msg = email.message_from_file(tempMessage) #parsing<br />
subject = msg.get("Subject")<br />
h = email.Header.Header(subject)<br />
dh = email.Header.decode_header(h)<br />
subject = dh[0][0]<br />
print "subject:", subject<br />
fileHandle.write ( subject )<br />
fileHandle.close()<br />
M.close()<br />
M.logout()<br />
这段代码的功能比较简单,就是登录进邮箱,然后搞到邮件,再然后把标题取出来打印到文件。(还是要赞python一个,这样的功能用不到30行代码就可以搞定~)至于具体的eml格式转换,还没写完,就不贴上来了。
关于登录,可能有的童鞋会认为直接把用户名密码写进代码不好,下面是另一种登录的方法,需要每次执行的时候都输入用户名、密码。这样的设计很适合在工程完成之后的实际使用。不过,测试的时候,还是上面那样比较省事~
<br />
M.login(getpass.getuser(), getpass.getpass())<br />