Hatena::ブログ(Diary)

今日覚えたこと RSSフィード

2017.10.16

macOSのスティッキーズの内容をiCloud DriveやDropboxやGoogle Driveなどに置いてどこからでも見れるようにする

macOSにはスティッキーズっていうアプリが標準で入ってる。付箋のような感じでメモをデスクトップ上に貼れるアプリ。まあわかるよね。

これが結構好きでよく使ってるんだけど、最大の難点が、ローカルにデータを保存するという点。そのMacデスクトップを見ないと、メモった内容を確認できない。他のMaciPhoneから見ることができない。2017年にもなったというのにまだそんなのがある。

Dropboxなどを使って同期させる方法はあるんだけど、別に同期したいわけではない。それぞれのMacにはそれぞれのスティッキーズがあっていいんだけど、違うMacのスティッキーズもちょっと見たいことがあるっていう感じ。

調べてみると、スティッキーズのデータは~/Library/StickiesDatabaseというひとつのファイルにまとまってるようだ。さっそく中身を見てみたら、各メモの内容がRTFになって結合されてるという感じだった。わりとカンタンそう。

なので、このStickiesDatabaseのファイルからRTFをそれぞれ抜き出して、任意のディレクトリに .rtf ファイルとして書き出すスクリプトを書いてみた。

stickies-backup

#! /usr/bin/ruby

require 'tempfile'
require 'fileutils'

# paths
in_path = File.expand_path('~/Library/StickiesDatabase', __FILE__)
out_path = File.expand_path('~/Library/Mobile Documents/com~apple~CloudDocs/StickiesBackup', __FILE__)

# directory initialize
backup_path = File.join(out_path, `hostname`.chop)
FileUtils.rm_rf(backup_path)
FileUtils.mkdir_p(backup_path)

# load original stickies
data = File.binread(in_path)
bytes = data.bytes

# make backup
found = false
array = nil
bytes.each_index do |i|
  if bytes[i...(i+6)] == '{\rtf1'.bytes
    found = true
    array = []
  end
  array << bytes[i] if found
  if bytes[(i-5)...i] == [0x7D, 0x01, 0x00, 0x00, 0x00]
    array.slice!(-5, array.size)
    rtf_file = Tempfile.new('rtf')
    txt_file = Tempfile.new('txt')
    File.open(rtf_file.path, 'w+b') do |file|
      file.write(array.pack('C*'))
    end
    `textutil -convert txt "#{rtf_file.path}" -output "#{txt_file.path}"`
    first_line = File.read(txt_file.path).lines[0].chomp
    filename = first_line.gsub(/[:\/]/, '') + '.rtf'
    puts filename
    FileUtils.cp(rtf_file.path, File.join(backup_path, filename))
    found = false
  end
end

これを適当にstickies-backupみたいな名前つけて、実行権限を与えておく。

in_pathのところはStickiesDatabaseの場所なので、普通はそのままでいいと思う。out_pathのところは、とりあえずiCloud Drive上に「StickiesBackup」っていう勝手なフォルダを作ってその中に書き出すようにしてある。DropboxGoogle Driveなど、他のフォルダがいい人は書き換えてね。

使い方

このコマンドを実行すると、out_pathで指定したフォルダの中に、そのMacのホスト名(hostnameコマンドの出力ね)でさらにフォルダを作って(すでにあったら消して作り直す)、RTF形式のファイルを出力する。スティッキーズ1件あたり1ファイルになる。ファイル名は1行目の文字列にしてみた(同じファイル名があったら上書きされるから注意してね)。

iCloud Driveに書き出したなら、iOS11で搭載された「ファイル」アプリで表示することができる。もちろん他のMacからでもiCloud Driveを開けばファイルが見れる。

あくまでスティッキーズから出力するだけで、スティッキーズに書き込む機能はない。生成されたRTFを編集しても何の意味もない。スティッキーズはひとつのファイルに全部入ってる形式なので、外部から書き換えたりしたら壊れやすそうな気がして、更新系はやめといた。

このコマンドを手動で実行するのが面倒なら、cronやlaunchdでも使うか、ファイルの更新を検知して自動で起動するとかもできるかも。

仕組み

まあ短いコードなので説明するほどでもないけど、バイナリデータとしてロードして、"{\rtf1" っていうデータを見つけたら抽出開始、"}" のうしろに 0x01 0x00 0x00 0x00 が続いてるデータを見つけたら抽出終了としている。抜き出したデータをRTFファイルとして書き出す。

RTFファイルを、一度 textutil コマンドにかけてる。これはmacOSに最初から入ってるコマンドで、文書っぽいファイルをいろいろ変換してくれる機能を持つ。今回は、RTFをプレーンテキストに変換した。1行目の文字列をファイル名として使いたいため、RTFから書式を排除したテキストが欲しかったので使った。

あとは、textutilコマンドで得たテキストの1行目をファイル名として、RTFファイルをout_pathにコピーする形で出力してる。

便利だよ

個人的にはこれで結構便利になった。スティッキーズ好きな人はぜひ使ってみて。

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/nacookan/20171016/1508165258