2009年3月22日日曜日

StickiesDatabase を読み書き

Stickies を外から読み書きしたりshare するアプリをいじろうとおもってObjective-Cと格闘した。

レガシーなものらしくて Mail.App とかとは違いsqlite とかには書いてない。


% file ~/Librar/StickiesDatabase
/nfs/xtakei/Library/StickiesDatabase: NeXT/Apple typedstream data, little endian, version 4, system 1000

どうやらObjective-C でobjectをシリアライズしてファイルに書き出すとこんなのになるらしい。中身のformat とか
もよくわからないのでいろいろ検索してみると


こんなものを発見。どうやらDocument class つくってほげほげやればいいらしい。
てことでStickiesImporterSupport ていうのがあったのでそのbundle だけをいただいて
ruby/cocoaで適当に工作する。とりあえず目標は読み書き。

まずload してStickiesDatabase.test へcopy

require "osx/cocoa"
require "osx/foundation"
require "document"
require "pp"
require "fileutils"

FileUtils.cp("/nfs/xtakei/Library/StickiesDatabase","/nfs/xtakei/Library/StickiesDatabase.test")


NSString とruby のstring の変換がいるとかFile のPath 用のobj にしたり。


z = OSX::NSString.stringWithString("~/Library/StickiesDatabase.test")
zz =OSX::NSUnarchiver.unarchiveObjectWithFile(z.stringByExpandingTildeInPath)

array = OSX::NSMutableArray.alloc.initWithArray(zz)


こんな感じでalloc する

このarray の中にundump したobject はいってるのだが

適当に


open("hoge.rtf","w+"){|f| f.write array[0].RTFDData.rubyString }

とか書き出してみる。


rtfd^@^@^@^@^C^@^@^@^C^@^@^@^S^@^@^@Pasted Graphic.tiff^G^@^@^@TXT.rtf^A^@^@^@.³
ä^A^@]^B^@^@V^@^@^@^A^@^@^@^@^@^@<80>öÔ^A^@­^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@
^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@
^@^@^@^@^@^@^@^@^@^@^@

ううむrtfd ってdirectory のようでこれじゃダメなようだ。
bundle のソースみてみると


-(NSString*)convertToHTMLsavingImagesToPath:(NSString*)imgPath {
NSAttributedString *str =
[[NSAttributedString alloc] initWithRTFD:[self RTFDData]
documentAttributes:NULL];
[str autorelease];

return [str convertToHTMLPreservingImages:YES
savingImagesToPath:imgPath
withTitle:[[self documentTitleOfLength:30] stringByAppendingString:@"..."]
];
}

NSAttributedString というのにして取り出すらしい。しかしあいかわらずすさまじいsyntax だ...
さらにみると


-(BOOL)exportAsHTMLToPath:(NSString *)path withTitle:(NSString *)htmlTitle
{
NSString *HTML = nil, *imgPath = [path stringByDeletingLastPathComponent];
if ([self containsAttachments])
HTML = [self convertToHTMLPreservingImages:YES savingImagesToPath:imgPath withTitle:htmlTitle];
else
HTML = [self convertToHTMLWithTitle:htmlTitle];

return [HTML writeToFile:path atomically:YES];
}

こんな感じらしい。


array[0].exportAsHTMLToPath("hoge.html","hoge/")


とかしてもダメだ....。どうやらruby cocoa のwrapper はattribue 付きのmethod は変態的な呼び出し
で _option名_option名 ...らしい


def str2path(str)
OSX::NSString.stringWithString(str).stringByExpandingTildeInPath
end

nsattr = OSX::NSAttributedString.alloc.initWithRTFD_documentAttributes(array[0].RTFDData)[0])
nsattr.exportAsHTMLToPath_withTitle(str2path(path),str2path(imgpath))



とりあえずhtml は吐けた...
こういうのは


OSX::NSAttributedString.alloc.initWithRTFD(array[0].RTFDData)[0], :documentAttributes=>null)
nsattr.exportAsHTMLToPath(str2path(path), :withTitle=> str2patp(imgpath) )


とかできるようにしていただけないのかと。

そんで書き込み書き込みは NSArchiver


array[0].setWindowFlags(1)
OSX::NSArchiver.archiveRootObject_toFile(zz,to_path("~/ast"))


とかしちゃっておわりらしい。

これでast をStickiesDatabase にcopy してみたらちゃんと反映されている。

zenback