いらないモノ、ひつようなモノ

書籍、音楽、そして若干のテクノロジー

乗り換え初投稿

catch.comもサービスを閉じた。
無料ブログもいつ亡くなるか分からない。
 
やはり自分が書いた日本語をどこかに
保存しておきたいという
生存本能が肩越しに話しかけてくる。
 
データのexport機能はそう考えると必須。
FC2などちゃんとそういう機能を備えている"らしい"。
 
が、しかし、考え方を逆にしてみた。
 
マスターデータを自分でしっかり持って、
それを無料ブログへexportすると考えればいい。
つまり
 
 外部メディアへ      オンライン
 いざという時の<=======>evernote======>blogなど
 バックアップ   enex データマスタ
 
 
こう考えれば、evernoteと連携しているブログが
一番というわけではてなダイアリーを選択。
 
って、昔からそうしている人はいるんでしょうねぇ。
 
ま、BLOGにしてから、それをevernoteにキャプチャ
すればいいって考えもあるかもしれない。
既存のものはそうやって保存するつもり。
 
次に問題となるのは、オフラインデータのバックアップ、
すなわち、写真、mp3、docファイルなど。
これらは外部メディアへバックアップしているが、
逆にオンラインのデータマスタ(evernote)に置いて
活用するという発想が脳裏をよぎる。
 
ということで、PCやNASに保存したファイルを
evernoteへまとめてアップロードするツールを作った。
 
ちなみに、写真を複数つかんで、それをたとえば
Windows版のEvernoteにDrag&Dropすれば、
ひとつのノートにまとめて写真が入る。
最初はこれでいいと思ったが、やってみると醜い。
見るときに不要なファイルまで落としてきて
時間はかかるし、いいことなしだ。
 
となると、ひとつのメディアを
ひとつのノートに入れたい。しかし、これはこれで
手作業が面倒。
 
ということで、狙ったファイルをまとめて読み込んで
しかもひとつづつアップロードするツールを作成した。
久しぶりにコーディングしたのでかっこ悪い。
 
正常系で必要なエラー処理、準正常系処理など、
時間がかかるので手を抜いている。
 
以下、備忘のため
 
  • 基本的な仕組み
    • ワイルドカードで指定してファイル名を取り込み
    • ファイル対象からMIMEタイプを決める
    • ファイル対象をBase64エンコード
    • さらに対象のハッシュ値を取得
    • evernote-export2.dtdに沿ってevernote出力形式のenexファイル(XML形式)を生成する
      • これはWindows版のツールでenexファイルとしてexportしたファイルの中身を見て、そこからURLを見て、そんでそれをダウンロードすれば分かるわけで、どこかに細かい仕様があるわけではない(いや、そういう風にあるのだが)
      • 今、気がついたが、http://xml.evernote.com/pub/evernote-export3.dtdってファイルを見ていた!つまり、こいつは今後もどんどんアップグレードするというわけでしょうね。
    • enexファイルを次々とインポートするために、evernote”付属”のenscriptを利用
      • enscriptはWindowsであればevernoteのプログラムが置いてある場所に一緒に置いてある
    • あとはほおっておけば勝手にSync
     
  • バグ、今後の改造
    • タグをまとめて入れたい
      • -f filepattern1 filepattern2 -t tag1 tag2  のような感じ
    • ノートブック指定は仕様上まだできないのかもしれないが対応したい。後から移動するのが面倒
    • エラー対応したい
      • 容量オーバー
      • 同期失敗
      • MIMEタイプの同定失敗
      • など
    • 対象ファイルのあるディレクトリと同じところにenexファイルを生成する。今はコード内を手動で切り替えてそれを削除する稼動するかを決めているが、これをアーギュメントで切り替えられるようにしたい
    • 今はコマンドラインから叩くが、これを窓にファイルをDrag&Dropすれば、、という楽々形態にしたい
    • テキストファイルは添付にせずに、展開して直接読めるようにしたい
    • zipにはどう対応?
    • tarは?
     
  • 使い方
    • rubyをインストールする!(ここが厄介!?)
    • この記事の最後にあるrubyのコードをCOPY&PASTE
    • 2evernote.rbというファイルに落とす
    • ファイルを置いたディレクトリに環境変数を変更してパスを通す
    • Evernoteが入っているディレクトリ、つまりEnscriptが置いてあるディレクトリにパスを通す
    • MS-DOSのコマンドラインを開く
    • コマンドラインでコマンド実行。以下、例
      • >>evernote.rb *.pdf *.pptx 201308*.jpg
    • 一応、Evernoteに入ったことを、アプリで確認
    • また、バグで同期されないこともあるので同期されていることを確認
  • 開発中に発生した課題
    • xml改行問題
    • xmlに改行があるだけで、読み込みエラーになる。一般的にもxmlに改行やスペースは禁物
    • UTC問題
      • JSTで書くと時間がずれる!というか、そういう仕様のようで、よく読んでませんでした
    • xml打ち間違え問題、凡ミスが怖いということ
      • resource-attributeを間違えるとファイルがattachmentという名前に
      • doctypeをen-en-noteなどと間違えると同期時のエラーに
 
で、evernotをオンラインのマスタにして、
実際にEvernoteからはてなに出すときに思ったこと。
 
ブログを介して表にだすってのは、出す直前に、
「あ、この日本語、ヘン!」とか
修正したいところがいっぱい見つかる。
それはあくまでマスタであるevernote側でやりたいから、
ブログ側にexportするときは作業としてやらねばいけない。
 
しかし面白いのが、evernoteに書いているときには、
個人的なものとして「ダダッー」っと文章を叩きつける。
ミスや細かい表現は気にしない。
 
一方、ブログに出すときってのは、
書いていることが、誰かの役に立つかな、とか、
こんなことが言いたいっ!ということを書くのだから、
そこに心理的なギャップがある。
 
この点をどうやって埋めるかというのは面白い問題だ。
 
昨今の炎上ってやつは、この心理的なギャップに起因している
んじゃないかな? いや、いや、いや、いや、
でもTwitterだから、最初から表に出ることが前提なわけで、
最初からその認識が間違った上で投稿しているんだろうな。
 
ふふふ。
 

 
 
require 'date'
require 'base64'
require 'digest/md5'
require 'rexml/document'
require 'mime/types'

def genEnex(b64v,hasv,fn)
odoc = REXML::Document.new()
odoc.add(REXML::XMLDecl.new(version="1.0", encoding="UTF-8"))
doctype= REXML::DocType.new(<<EOS)
en-export SYSTEM "http://xml.evernote.com/pub/evernote-export2.dtd"
EOS

odoc.add(doctype)

root = REXML::Element.new("en-export")
note = REXML::Element.new("note")
title = REXML::Element.new("title")
content = REXML::Element.new("content")
en_note = REXML::Element.new("en-note")
en_media = REXML::Element.new("en-media")
created = REXML::Element.new("created")
resource = REXML::Element.new("resource")
data = REXML::Element.new("data")
mime = REXML::Element.new("mime")
resource_attributes = REXML::Element.new("resource-attributes")
source_url = REXML::Element.new("source-url")
file_name = REXML::Element.new("file-name")
attachment = REXML::Element.new("attachment")

root.add_attribute("export-date","")
root.add_attribute("application","A9A9")

odoc.add_element(root)
root.add_element(note)
note.add_element(title)
title.add_text(File.basename(fn))
note.add_element(content)
note.add_element(created)

created.add_text(Time.now.gmtime.strftime("%Y%m%dT%H%M%SZ"))

note.add_element(resource)
resource.add_element(data)
data.add_attribute("encoding","base64")
data.add_text(b64v)
resource.add_element(mime)

mime.add_text(MIME::Types.type_for(fn).first.to_s)
resource.add_element(resource_attributes)
resource_attributes.add_element(source_url)
source_url.add_text("file://"+fn)
resource_attributes.add_element(file_name)
file_name.add_text(File.basename(fn))

resource_attributes.add_element(attachment)
attachment.add_text("true")
en_note.add_element(en_media)
en_media.add_attribute("hash",hasv)
en_media.add_attribute("type",MIME::Types.type_for(fn).first.to_s)

doctype= REXML::DocType.new(<<EOS)
en-note SYSTEM "http://xml.evernote.com/pub/enml2.dtd"
EOS
istr=doctype.to_s+en_note.to_s
cdata=REXML::CData.new(<<EOS)
<?xml version="1.0" encoding="UTF-8"?>
#{istr}
EOS
content.add(cdata)


ofile=File.basename(fn,File.extname(fn))+".enex"
File.open(ofile,"w:UTF-8") do |outfile|
odoc.write(outfile, -1)
end
end

for arg in ARGV
p Dir.pwd+"/"+arg
for impFile in Dir.glob(Dir.pwd+"/"+arg)

b64 = Base64.encode64 File.open(impFile,'rb').read
has = Digest::MD5.hexdigest(File.open(impFile,'rb').read)
fullname=File.expand_path(impFile)
extname =File.extname(impFile)
basename=File.basename(impFile)
genEnex(b64,has,fullname)
#"enscript importNotes /s "+"\""+File.basename(fullname,extname)+".enex"+"\""
system("enscript importNotes /s "+"\""+File.basename(fullname,extname)+".enex"+"\"")
# system("rm "+"\""+File.basename(fullname,"."+extname)+".enex"+"\"")
end # end of for
end