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にコピーする形で出力してる。

便利だよ

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

2017.01.18

Time Capsuleを買った(5年半ぶり2台目)

Time Capsuleを買ったっていうか、買い換えた。

f:id:nacookan:20170118003626p:image:w300

Amazon | APPLE AirMac Time Capsule - 3TB ME182J/A | アップル | 外付ハードディスクドライブ | パソコン・周辺機器

前回買ったのは2011年7月なので、5年半ぶりとなる。

たくさんの機能

Time Capsuleは機能がたくさんある。ブロードバンドルーター、有線LANハブWi-FiアクセスポイントWi-Fi拡張、Time MachineバックアップHDDNASUSB-HDDプリンターの共有化、どこでもMyMacで家の外からでもデータにアクセス、ほんとたくさん。

Time MachineバックアップHDDとして使うってことは、自動的にMacバックアップを取り続けて、いざMacHDDがクラッシュしたときの復旧もできるし、操作ミスでファイルを消したり上書きしたりしたときの復活もできる、何世代も保存されてるので過去のファイルの修正の歴史を確認したりもできる、新しいMacを買ったときのデータ移行にも使える。素晴らしい。

たくさん機能があるんだけど、ブロードバンドルーターとして使う場合は、基本的にはインターネット回線が来てる場所の近くに設置しなきゃいけない。でもそこがバックアップ用の大事なHDDとか、共有プリンターとかを設置する場所として適切かどうかは微妙なところ。1台でなんでもできるせいで、置き場所が難しい問題を抱えてる気はする。まあでもそれくらいいろいろな機能がある。

自分の場合は、最初のTime Capsuleを買った当時は、Time MachineバックアップNASの機能を使っていた。

でもあとになってNASはやめた。メインのMacの内蔵HDDが時代の変化で大きくなり、外部HDDが必要なくなったのと、共有のためにはGoogle Driveを使うことにしたため。

その代わり、家のWi-Fiを5GHz化するために、Wi-Fiアクセスポイントの機能を使うことにした。さらに、5GHzのWi-Fiは安定性は高いけどエリアが狭くなるので、AirMac Expressを2台追加して、Wi-Fi拡張の機能も使うようにした。

買い換えたくなった

そんな感じで5年半使っていて、いろいろまた事情が変わってきた。

  • HDDがいっぱいになった(古いバックアップを自動で消しながら新しいバックアップを保存してくれるので、通常そこまで問題ではないけど、新しいMacを買い増すのは無理な感じ)
  • そろそろ、家のWi-FiIEEE802.11ac対応にしたい(以前のモデルは非対応だけど今のモデルは対応している)
  • たまに、おそらく熱が原因で停止するようになるなど、調子が悪い感じがする
  • HDDの動作音が大きくなってきた気がする

まあHDDを5年以上使うってだけでちょっと怖い。

そんなわけで、別に新モデルが出たタイミングとかじゃないけど、買い換えることにした。

本当は、搭載HDDがもっと容量が増えたモデルが出てから買いたかったところではある。いまどき3TBではちょっとさみしい。でもWi-Fiの規格が802.11acからしばらく進化してないので、新しいモデルは特に作らないのかな。。。なんならAppleがこの分野から撤退する噂もあるけど。。。

幸運にもバックアップが役に立ったことはなかった

5年半の間、延べ5台のMacバックアップをとり続けてきたけど、一度もバックアップデータを使ったことはなかったと思う。MacHDDがクラッシュしたこともないし、間違って消したファイルを復活させたこともない。

もちろんバックアップデータを使わない方が幸せな話ではある。あるいは、実際にバックアップデータを使わなくても、バックアップがあるから大丈夫という安心感で、日々Macを気軽に使うことができていたという意味では大きな価値があったと言える。

セットアップ

セットアップがなかなかすごかった。

とりあえず電源をつないだら、iPhoneの設定→Wi-Fiのところに新しいメニューが出てきた。

f:id:nacookan:20170118014838p:image

もちろんMacAirMacユーティリティを使っても同じことができたけど、今回はこのままiPhoneで設定してみることにした。

進んでみると、既存のTime Capsuleを、新しいTime Capsuleに置き換えるための設定が推奨された。もともと家にTime Capsuleがあることがわかっていて、今回新しいTime Capsuleを追加したから、これは置き換えなんじゃないかと判断されたわけだ。すごいね。

しかも、地味にちゃんと画面内のTime Capsuleの絵が実物と同じものになってる。

確かに置き換えたいので、この機能を使って設定を続けた。

f:id:nacookan:20170118014833p:image

f:id:nacookan:20170118014828p:image

f:id:nacookan:20170118014823p:image

こんな流れ。LANケーブルを抜いて新しい方につなぐタイミングまで教えてくれた。それ以外は特に何もしてない。「次へ」を押すか、押さなくても自動で進んだりして、設定が終わった。そして従来通り使えてる。Wi-Fiを拡張していた2台のAirMac Expressも何もしてないけどそのまま動いてる。

昔は、こういうのを設定したりするのも楽しいもんだったし、自動でなんでもやられてしまうと、なんか信用できない感じもあった。けど最近はもうこんなことでハマってトラブルに巻き込まれたくないし、自動設定でも中でどんなことやってるかはだいたいわかるようになったので、機械を信用して任せちゃう場面も増えた。

これをiPhoneだけでやれちゃってるのもすごい。それはつまり、最近は珍しくないパソコンを持ってない人でも大丈夫だし、最初だけ有線LANでつないで設定するとかも必要無いわけだ。

ちょっと画面の文章はわかりにくい気がするけど、まあそれでもよくできてる。

進化した点

今後は新しいTime Capsuleで、IEEE802.11acが使えるようになったし(Wi-Fiを拡張しているAirMac Expressは対応してないので、このTime CapsuleのWi-Fiが届く範囲だけIEEE802.11acって感じだけど)、HDDは3TBになってたくさんバックアップが入るし、形状が変わって電波の性能もよくなったらしい。

まああとは熱で停止する問題が改善していることに期待。これはしばらく使えばわかると思う。

2016.12.02

Exif情報を元にJPEGファイル名をリネームするJavaScript for Automation(2016年バージョン)

2014年に書いたこれ

を直した。

JPEGのファイル名を、Exif情報を元にリネームするスクリプト

iPhoneやデジカメで撮った写真のファイル名が、

img_20141024_012345_Apple_iPhone6_1.jpg

こんな感じになるスクリプト

「img + 年月日 + 時分秒 + カメラメーカー名 + カメラ名 + 連番 + .jpg」っていうルールでリネームする。連番は、カメラで連写などして年月日時分秒まで一致した場合にカウントアップする。

複数のカメラで撮った写真をひとつのフォルダにまとめて保存し、さらにレタッチしてファイルのタイムスタンプが変化してる場合などに、こういう風にファイル名がついていれば整理しやすい。

Exif情報を元にJPEGファイル名をリネームするJavaScript for Automation - 今日覚えたこと

当時の説明がこんな感じ。

コード

ソースコードは以下。

function openDocuments(docs) {
    var app = Application.currentApplication();
    app.includeStandardAdditions = true;
    
    var count = 0;
    for(var i = 0; i < docs.length; i++){
        var src = docs[i].toString();
        if(!/\.jpe?g$/i.test(src)) continue;
        
        // Get Exif
        var sips = app.doShellScript('sips -g all "' + src + '"');
        var lines = sips.split(/\r\n|\r|\n/).slice(1);
        var exif = {};
        for(var j = 0; j < lines.length; j++){
            /^\s*([^:]+): (.+)$/.test(lines[j]);
            exif[RegExp.$1] = RegExp.$2;
        }
        
        if(!exif.creation){
            // Get FileInfo
            var fileInfo = app.doShellScript('GetFileInfo "' + src + '" | grep created');
            exif.creation = fileInfo.replace(/^.+?([0-9]+)\/([0-9]+)\/([0-9]+) ([0-9:]+)/, '$3:$1:$2 $4');
        }
        if(!exif.make) exif.make = 'unknown';
        if(!exif.model) exif.model = 'unknown';
        
        // Generate Name
        var parent = src.replace(/[^\/]+$/, '');
        var dst;
        var index = 1;
        while(true){
            dst =
                parent +
                'img_' +
                exif.creation.replace(/:/g, '').replace(/ /, '_') + '_' +
                exif.make.replace(/[^a-z0-9-]/ig, '') + '_' +
                exif.model.replace(/[^a-z0-9-]/ig, '') + '_' +
                index.toString() +
                '.jpg';
            var ret = app.doShellScript('if test -e "' + dst + '"; then echo 1; else echo 0; fi');
            if(ret == '0') break;
            index++;
        }
        
        // Rename
        app.doShellScript('mv "' + src + '" "' + dst + '"');

        // Live Photos
        var lp_src = src.replace(/\.JPG$/i, '.MOV');
        var ret = app.doShellScript('if test -e "' + lp_src + '"; then echo 1; else echo 0; fi');
        if(ret == '1'){
            var lp_dst = dst.replace(/\.jpg$/i, '.mov');
            app.doShellScript('mv "' + lp_src + '" "' + lp_dst + '"');
        }

        count++;
    }
    
    app.displayAlert(count.toString() + ' file' + (2 <= count ? 's' : '') + ' renamed.');
}

macOS Sierraで動作確認した。特にOSの新機能とかを使ってるわけではないと思うので、JavaScript for Automationに対応しているYosemite以降なら動くと思う。

スクリプトエディタに上記のコードをコピペして、好きな場所にアプリケーション形式(.app)で保存する。

あとはそのappファイルに対してJPEGファイルをドラッグ&ドロップするとリネームされる。複数のファイルをドロップしてもOK。

2014年バージョンからの変更点

  • Exifに日付がない場合、代わりにファイルのタイムスタンプの日付を使うようにした
  • Exifにカメラメーカーやカメラ名が無い場合、エラーにならないでunknownとして動作するようにした
  • Live Photosに対応した。JPGと同じファイル名のMOVが存在している場合、MOVも同じようにリネームするようにした。

こんなところ。具体的には、SNOWで撮った写真にExifが入らないようなので、それでいちいちエラーにならないようにしたのと、iPhone 6s以降の新機能のLive Photosに対応した感じ。

まあ2年前には想定してなかった状況に対応したってこと。今後もまた何かあったら直すね。

2016.08.21

MacBook用のケースを買った

こんなの。

MacBookを持ち歩く際に入れておくケース。簡単に出し入れできるレザーのが欲しいと思って探していたら、この国立商店のケースが評判が良かったっぽいので買ってみた。

https://farm9.staticflickr.com/8322/28490984043_c2cdafde17.jpg

これはMacBook(12インチのやつ)専用に作られてるので、ほんとピッタリ。しかもレザーの感じも良いし、内側は厚めのフェルトでしっかり守られている。満足度高い。

ちなみに、もちろんMacBook Air用とかもあるので自分にあったやつを選べるよ。

キズが気になっちゃう

そもそもなぜMacBookをケースに入れるかと言うと、カバンにMacBookを出し入れする際に、カバンのファスナーとかの金具に当たったりとか、あとはカバンの中の他の荷物に当たったりとかで、MacBookにキズが付いたり壊れたりするのを防ぐため。

なんだけど、このケースがレザーだから、今度はこのケースのキズが気になっちゃう。レザーは、ひっかき傷や、硬い物を押しつけるとあとが付きやすいわけで、実際このケースを買って2ヶ月くらいたつけど、いろいろとダメージを受けている。冒頭の写真を見ても少しわかると思う。

まあそれがレザーの味になるし、仕事してる証だってことになるのかな。。。

確かに、無数にキズが付けば気にならなくなってくるだろうし、クリーム塗ったり布で磨いたりすればキズもなじんできて見えにくくなるので、大切に長く使っていればいいか。

しかしこのMacBookをそこまで長く使うかどうかわかんない。普通に考えると2〜3年だろうし、買い換えるときに同じサイズのMacBookがまだあればいいんだけど。

まあ1年とか2年とか使ったタイミングで、もしそのとき覚えてたら、レザーの経年変化についての報告とかはできるかも。

2016.08.13

Ankerの7ポートUSB 3.0ハブを買った

https://farm9.staticflickr.com/8813/28650920180_7263cd80ea.jpg

iMacは接続ポート類が全部背面なので、接続する機器がほぼ固定されてるLANとか外付けディスプレイとかはいいんだけど、USBは日常的に抜き差ししたいのでつらい。ってことでUSBハブを買った。

  • ポート数が比較的多くて
  • 机の上で使いやすいようにポートが横一列に並んでるやつで
  • 全部USB3.0で
  • セルフパワーで
  • 持ち運ぶつもりは無いのでサイズや重さはこだわらない

ってことで探したところ、いくつかあったけど、このAnkerの7ポートはまあ値段もそこまで高くないのでこれにした。

実物を見てみると、ペラペラのプラスチックな感じがして、ちょっと心配はある。でもとりあえず、USB3.0の機器を現時点でたぶん持ってないのでよくわかんないけど、iPhoneやiPad、Androidもいくつか、デジカメ、あとはUSBメモリなどをつないだ感じでは普通に使えた。

あとはあちこちでレビューなどを読むと、使える機器はもちろん使えるけど、たまに使えない機器があるとか。使えないときはiMacの背面にもまだポートはあるので、どうにかなるとは思う。

ハブ経由でもiPadの充電ができた

ちょっと良かったのは、このハブにつないだiPadが充電できた点。iPad mini 4とiPad Pro (9.7インチ)で確認した。

今までは、USBハブからのiPadの充電はなかなか難しかった。iPadをiMacと直接つなぐのはいいけど、USBハブを経由すると「充電していません」になっちゃう。

同期やiTunesバックアップのためにMacとつないで、そのあと充電のために別な充電器につなぐという、かなり面倒なことをやる必要があった。

ところがこのハブだと、ちゃんと充電されてる。これはいいね。非常にシンプルになる。とはいえ、充電速度は決して速くない気がする。まあ利用シーンを考えれば、Macにつないで通信と共に充電したいときは、別に充電を急いでる場面ではないと思うので、あんまり気にならないかな。

USB3.0のハブなら、iPadの充電ができるってのは普通のことなのかな?よくわからんけど。

まあ良い

7ポートあれば当面は足りるし、USB3.0なので今後新しい何かが増えても大丈夫そう。形状やポートの並びは、持ち運びとかは重視してなくて、机の上などに据え置いて使う方を想定してるっぽいので、自分の用途には当てはまってる。

今のところ使えない機器もないし、まあこれで良かったかなと思う。