最初のエントリでも書いたように、このブログはEvernoteで書いてる(この文章自体も)。
APIキーの取得については以前書いたのでそちらを参照ください。
Evernoteからブログへのデータ取り込み部分のソースを出しておく。クラス構造とか設定ファイルとかは端折って、実際に動くところのみ。Evernote公式のrubyライブラリはいまいち使いにくい。もうちょっとrubyっぽいサードパーティのwrapperとかあってもよさそうだけど、今のところなさそうだし作るのもだるい。
処理の流れとしては、
- 自分のアカウントで認証
- "blog"というタグが含まれている全ノートを抽出
- ノートを一つずつ舐めて、自分のWebアプリにデータ取り込み
認証
とりあえず、関連するライブラリをrequireしてから認証処理。この辺はサンプルのまま。
require "thrift"
require "Evernote/EDAM/user_store"
require "Evernote/EDAM/user_store_constants.rb"
require "Evernote/EDAM/note_store"
require "Evernote/EDAM/limits_constants.rb"
userStoreTransport = Thrift::HTTPClientTransport.new("https://www.evernote.com/edam/user")
userStoreProtocol = Thrift::BinaryProtocol.new(userStoreTransport)
userStore = Evernote::EDAM::UserStore::UserStore::Client.new(userStoreProtocol)
authResult = userStore.authenticate("YOUR_USER_NAME", "YOUR_PASSWORD",
"CONSUMER_KEY", "CONUMER_SECRET")
evernote_user = authResult.user
authToken = authResult.authenticationToken
ここで作ったauthTokenを持ち回してAPIで使う。
ノートにアクセスするための準備
noteStoreUrl = "http://www.evernote.com/edam/note/" + evernote_user.shardId
noteStoreTransport = Thrift::HTTPClientTransport.new(noteStoreUrl)
noteStoreProtocol = Thrift::BinaryProtocol.new(noteStoreTransport)
noteStore = Evernote::EDAM::NoteStore::NoteStore::Client.new(noteStoreProtocol)
ここで作ったnoteStoreでノートにアクセスする。
ノートを検索
filter_tag = "blog"
filter = Evernote::EDAM::NoteStore::NoteFilter.new
filter.words = "tag:#{filter_tag}"
res = noteStore.findNotes(authToken, filter, 0, 100)
このfilter.wordsにはEvernoteクライアントでも使える検索式が書ける。たとえば、tag:で始まるのはタグだし、単に文字列を入れるとその文字列で検索される。
後は、上の検索で引っかかったノートの情報をmongoDBにコピーする処理。同時に、添付されている画像ファイルもローカルに落としてる。mongoDBへのアクセスはいまのところMongoMapperを使っている。見てわかるようにActiveRecordとほぼ同じインターフェース
XSLTを使ってるのは、Evernoteのノートは独自のXMLで保管されているので、それをhtml変換するため。XSLTの中身は以前紹介したやつ。
note2blog = Nokogiri::XSLT(File.read('xslt/note2blog.xslt'))
res.notes.each do |note|
entry = Entry.find_or_initialize_by_evernote_key(note.guid)
next if entry.updated_timestamp.to_i == Time.at(note.updated / 1000).to_i
if note.resources
note.resources.each do |resource|
data = noteStore.getResource(authToken, resource.guid, true, true, true, true)
hex = data.data.bodyHash.unpack('H*').first
ext = case data.mime
when 'image/png'
'png'
when 'image/jpeg'
'jpg'
else
raise "Unknown mime type: #{data.mime}"
end
File.open("publichttp://blog.madoro.org/mn/images/#{hex}.#{ext}", 'w') {|f| f.write(data.data.body) }
end
end
entry.user = user
entry.title = note.title
tags = noteStore.getNoteTagNames(authToken, note.guid)
tags.delete_if {|a| a == filter_tag}
entry.tags = tags
content = noteStore.getNoteContent(authToken, note.guid)
entry.text = note2blog.transform(Nokogiri::XML(content)).to_s
}
entry.updated_timestamp = Time.at(note.updated / 1000)
entry.published_timestamp ||= Time.at(note.updated / 1000)
entry.status = Entry::Published
entry.save!
end
記事の内容についての質問、苦情、間違いの指摘等なんでもtwitterでどうぞ。 Tweet