evernote 実質有料化! Simplenote への移行

あらゆる作業の生産性に直結するノートアプリ。evernoteが実質有料化してから難民状態だったが、遂に安住の地としてSimplenoteを選択する事に。数ヶ月の間、onenoteも使ってしまったので、移行は極めてややこしい状態に。onenoteからSimplenoteへの移行は言語的にハードルが高い。ネット上の情報も多めなevernoteからSimplenoteへの移行を目指す。当然、onenoteにしかない差分もあるが、過去分の更新についてはある程度切り捨てるのと、新規ノートについては手動での移行を実施する。

まずはevernoteからの情報抽出だが、どうやらsqliteで格納されているらしい。sqliteが使える環境であれば、データへのアクセスはそれほど難しくないはず。自分のクライアントの中にはmacもあるので、mac上のevernoteにsqliteでアクセスしてみると、あっさりデータを覗く事ができた。sqliteは触った事がないので、ぐぐりながらノートデータを探す。tagをまったく使っていなかった自分はノートブック情報の入っているZENNOTEBOOKとノート情報の入っているZENNOTEから抽出すればよさそう。

cd /Users/USERNAME/Library/Application Support/com.evernote.Evernote/accounts/www.evernote.com/12345678
sqlite3 LocalNoteStore.sqlite
.tables
ZENBUSINESSNOTEBOOK  ZENOSXATTRIBUTE      Z_5TAGS
ZENCLIENTPREFERENCE  ZENPUBLISHING        Z_METADATA
ZENEXPUNGE           ZENRESOURCE          Z_MODELCACHE
ZENLINKEDNOTEBOOK    ZENSAVEDSEARCH       Z_PRIMARYKEY
ZENNOTE              ZENSHAREDNOTEBOOK
ZENNOTEBOOK          ZENTAG

.headers on
select z_pk,zname from zennotebook;
select z_pk,znotebook,zlocaluuid,ztitle from zennote limit 10;
select zlocaluuid,ztitle,zname from zennote zn left outer join zennotebook znb on znb.z_pk=zn.znotebook limit 10;

ここからデータを抽出できれば、あとはSimplenoteのAPIを使ってデータを放り込めばよいだけ。ネット上にある情報はmacでの作業を前提としていたので一旦macで進めてみようと思ったが、perlのモジュールすらまともに入れられない始末。私のmac力って。。。早々に諦めてevernoteのデータをCentOSサーバへコピーして、Linuxで作業する事に。ノートの実データは結局ファイルになっていて、しかもHTML表記。これをtextに変換する必要がある。macだとtextutilというコマンドを使うようだが、Linuxにそういうコマンドは存在しない。調べた結果、w3mを使う事にした。

yum install w3m
w3m -T text/html -dump content.enml

ネット上に公開されているperlの変換スクリプトを元に自分用の移行スクリプトを作成する。こういった情報提供に心から感謝します(スクリプト本体は記事末尾を参照)。スクリプトの実行に必要なモジュールがかなり多く、わりと手動で入れないといけない。CPAN使えばよかったのかもしれないけど、ささっと動かなかったので、ごりごりとインストールしていってしまった。かなり手間だったけど、以下のモジュールを入れる事で動作させる事ができた。

cd /usr/local/src
wget http://search.cpan.org/CPAN/authors/id/S/SA/SATOH/Config-Pit-0.04.tar.gz
tar xzf Config-Pit-0.04.tar.gz
cd Config-Pit-0.04
perl Makefile.PL
make
make install

wget http://search.cpan.org/CPAN/authors/id/Z/ZE/ZEFRAM/Lexical-SealRequireHints-0.010.tar.gz
tar xzf Lexical-SealRequireHints-0.010.tar.gz
cd Lexical-SealRequireHints-0.010
perl Build.PL
./Build
./Build install

wget http://search.cpan.org/CPAN/authors/id/L/LE/LEONT/Const-Fast-0.014.tar.gz
tar xzf Const-Fast-0.014.tar.gz
cd Const-Fast-0.014
perl Build.PL
./Build
./Build install

yum install --enablerepo=epel,remi,rpmforge perl-Any-Moose perl-Const-Fast perl-Devel-Declare perl-Mouse perl-PPI perl-Test-Exception perl-Test-Warn perl-Data-Alias
wget http://search.cpan.org/CPAN/authors/id/B/BA/BAREFOOT/Method-Signatures-20160315.tar.gz
tar xzf Method-Signatures-20160315.tar.gz
cd Method-Signatures-20160315
perl Build.PL
./Build
./Build install

yum install --enablerepo=epel,remi,rpmforge perl-DateTime perl-HTTP-Cookies perl-JSON perl-Moose perl-MooseX-Types-DateTime perl-MooseX-Types-Path-Class perl-Try-Tiny perl-namespace-autoclean perl-libwww-perl
wget http://search.cpan.org/CPAN/authors/id/I/IO/IOANR/WebService-Simplenote-0.2.1.tar.gz
tar xzf WebService-Simplenote-0.2.1.tar.gz
cd WebService-Simplenote-0.2.1
perl Build.PL
./Build
./Build install

このスクリプトによる移行後に、Simplenote側でインポートしたノートがゴミ箱に入ってしまうのが回避できなかったが、そこはもう気合いで全ノート救い出した。移行したあとに気付いたんだけど、evernote側でゴミ箱に入っていたようなノートも復活してしまった。Simplenote側だともう見分けつかないしね。。。移行作業をする前にevernoteのゴミ箱は空にしておく事を忘れないように。ちなみに移行時にノート数がわかった。全部で1500ノートあったよ。これをゴミ箱から取り出す労力。。。とはいえ、これを終えるとあらゆるプラットフォームからアクセスできるシンプルなノート環境を堪能することが出来た。うんうん、生産性10倍は上がったなw

最後に自分が利用した移行スクリプトを参考までに。

#!/usr/bin/perl

use strict;
use warnings;
use utf8;
use DBI;
use Encode;
use File::Spec;
use Config::Pit;
use Log::Any::Adapter ('Stdout');
use WebService::Simplenote;
use WebService::Simplenote::Note;
use Data::Dumper;

our $EvernoteUserId;
our $Basedir = File::Spec->catfile(
    $ENV{HOME},
    qw(evernote),
);

my $sn_config = pit_get('simplenote.com', require => +{
    email    => 'en_user',
    password => 'en_pass',
});

my $sn = WebService::Simplenote->new(%$sn_config);

my $notes = get_notes();

for my $note (@$notes) {
    my $note_obj = WebService::Simplenote::Note->new(
        content => $note->{content},
    );
    $note_obj->tags($note->{tags});
    $sn->put_note($note_obj);
}

sub get_notes {
    my $dbh = dbh();
    my @notes = ();
    my $note_sth = $dbh->prepare(
        'select zlocaluuid,ztitle,zname from zennote zn left outer join zennotebook znb on znb.z_pk=zn.znotebook'
    );
    $note_sth->execute;
    while (my($uuid, $title, $notebook) = $note_sth->fetchrow_array) {
        warn qq|reading data from [$uuid]\n|;
        my $note_content = get_note_from_uuid($uuid);
        push @notes, +{
            content =>
                join("\n", map { decode('utf-8', $_) } ($title, $note_content)),
            tags    => [ $notebook ],
        };
    }
    return \@notes;
}

sub get_note_from_uuid {
    my $uuid = shift;
    my $file = "$Basedir/content/$uuid/content.enml";
    my $command = "w3m -T text/html -dump $file";
    my $textnote = `$command`;
    return $textnote;
}

{
    my $dbh;
    sub dbh {
        return $dbh if $dbh;
        return $dbh =
            DBI->connect("dbi:SQLite:dbname=$Basedir/LocalNoteStore.sqlite");
    }
}

コメントを残す

メールアドレスが公開されることはありません。

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)