いとこんのメモ帳

コードの断片を置いたりします

ThinkPad W530 届きました

f:id:ito_konnyaku:20130915133026j:plain

背景

今まで使ってた 15" MacBook Pro early 2011 が、AMD の discrete GPU が逝ってしまったのか、非常に調子が悪くなってました。

仕事で使ってるので、完全に死んでしまうといろいろとまずいので、新しいマシンを調達します。

機器選定

仕事柄、多数の VM を立ち上げる必要があるので、それに見合ったスペックが必要となります。そこで、いわゆるモバイルワークステーションが選択肢となります。

候補は MacBook Pro 15" Retina か ThinkPad W530.

当初は MacBook Pro Retina を考えてましたが、メモリとストレージがオンボード実装なので、これはちょっと NG. これで ThinkPad W530 を、ということになりました。

他社のはキーボードがテンキー付きだったり、やたらデカく重かったり。。

構成

  • CPU: Core i7 3740QM (2.7GHz, 6MB)
  • OS: Windows 8 Pro (64-bit) 日本語
  • Display: 15.6 Full HD w/ カラーセンサー
  • GPU: NVIDIA Quadro K1000M 2GB
  • RAM: 16GB PC3-12800 DDR3 2 slot
  • Keyboard: US w/ back light
  • Storage: 256GB SSD
  • 指紋センサー
  • Bluetooth 4.0, Intel Centrino Ultimate-N 6300
  • Office Home and Business 2013
  • 3 年間オンサイト修理 and アクシデント・ダメージ・プロテクション

しめて \358,229 ですが、これに期間限定クーポンの 25% 引きをきかせて、

\276,539

でした。割引額だけでウルトラブック買えちゃいます。

おもしろそうなのでキャリブレータも付けてみました。Lightroom で RAW 現像したりするので、役に立つかな、と。

メモリスロットは 4slot 搭載、オーダー時実装 2slot 16GB なので、8GB のモジュール 2 枚買ってきて取り付ければ 32GB にも UG 可能な感じですかね。

到着まで

  • 9/3 Web にてオーダー
  • 9/4 決済完了
  • 9/8 工場出荷
  • 9/11 国内 lenovo 配送センター到着
  • 9/13 国内発送 <- このタイミングでヤマト運輸の伝票番号通知
  • 9/15 到着

オーダー時の見積もりは、9 営業日発送、+4 営業日お届けだったので、予定よりも早く届いた感じですね。

軽くレビュー

一番懸念してたのがキーボード。まぁ Web 上ではいろいろな批評がありましたが、個人的には全然問題ないです。MBP よりも遙かにいいキーボードが搭載されています。

ディスプレイも鮮やかでいいですね。

このレビュー書いてる時点ではもう Haswell, 3k ディスプレイな W540 が発表されてますが、8 万近い値引き、今までの流れをある程度汲んだ筐体、非テンキー搭載、ということで特に失敗した感はないかなーと (言い訳

3 年オンサイト保証も付けたので、しばらくはこいつをメインにしていく感じです

 

MBP 修理いくらかかるかな。。。

MacRuby で Pasteboard 監視・HTML スクレイピング・WebView 操作

どういうのを作るか

英文のリソースを読んでいる最中、わからない単語が出てきたらオンラインの Cobuild (ここ) で検索してるんだけど、いちいちキーボード叩いたり、コピペするのはめんどくさい。

これを、Pasteboard を監視し、単語がコピーされたら自動でその単語の意味を表示出来たら難しい英文読むときに捗るかなと思い、ツールを作ってみることに。

どうやら、さくっと OS XGUI アプリを書きたい時に MacRuby がなかなかよいらしいので、これでちょっと組んでみる。OS X のバージョンは 10.7

MacRuby のインストール法、プロジェクトの作成は省略。

WebKit.framework の追加

WebView を使うには、WebKit.framework が必要になるので、これへのリンクを張る。

f:id:ito_konnyaku:20130117021245j:plain

アクセサの準備

WebView と連携するためでもある、アクセサを準備。AppDelegate.rb にはもう既に attr_accessor :window と記述されてるので、同じように attr_accessor :browser とかしてアクセサを準備する。

WebView 配置、アウトレット接続

こんな感じに InterfaceBuilder でさくっと WebView を配置。

f:id:ito_konnyaku:20130117022237j:plain

後は左ペインの "AppDelegate" から "WebView" へ右クリックしながらドラッグするなどして、先ほど追加したアクセサに接続。

Pasteboard 監視

OS X での Pasteboard は、コピーした瞬間に通知を受け取れるような API がなさそうなので、ポーリングをかけるとする。AppDelegate.rb にこんな感じで Pasteboard を監視するコードを書く。

def applicationDidFinishLaunching(a_notification)
    beginObservingPasteboard
end

def beginObservingPasteboard
    @changeCount = NSPasteboard.generalPasteboard.changeCount
    
    NSTimer.scheduledTimerWithTimeInterval(1,
                                           target:self,
                                           selector:"observePasteboard:",
                                           userInfo:nil,
                                           repeats:true)
end

def observePasteboard(timer)
    pboard = NSPasteboard.generalPasteboard
    if pboard.changeCount > @changeCount then
        pasteboardChanged pboard
    end
    
    @changeCount = pboard.changeCount;
end

def pasteboardChanged(pboard)
    classes = [ NSString ]
    objects = pboard.readObjectsForClasses(classes, options:nil)
    copied_str = objects[0]
    openURL("http://dictionary.reverso.net/english-cobuild/#{copied_str}");
end

beginObservingPasteboard メソッドで、タイマを登録。selector はただ単にメソッド名の文字列を渡せばよい模様。そして observePasteboardクリップボードのアイテムが増えたか判定、増えてたら (= コピーされたら) pasteboardChange を call, コピーされた文字列を取り出して、Web サイトアクセス開始する。openURL については後述

HTML スクレイピング

ただ単に Web サイトを表示するだけならここまでで OK だが、上述のサイトは不要な部分が多いので、ごにょごにょすることにする。

XML パーサでいろいろとやるのもいいけど、WebView に一旦コンテンツを読み込ませてから、内部の DOM ツリーを操作できるようなので、このアプローチでいくことに。

まずは HTML を読み込ませる、非表示の WebView を作成。AppDelegate の applicationDidFinishLaunching で作ってインスタンス変数にでも格納しておく。

@domParser = WebView.new
webFrameLoadDelegate = WebFrameLoadDelegate.new
webFrameLoadDelegate.browser = self.browser
@domParser.setFrameLoadDelegate(webFrameLoadDelegate)

この domParser には、フレームのロード完了通知を受け取るため、WebFrameLoadDelegate を登録する。この WebFrameLoadDelegate クラスは、外部のファイルに切り出している。WebFrameLoadDelegate には、結果表示も任せたいため、browser への参照を渡しておく。

前述の openURL メソッドで、HTML コンテンツのロードを開始する。

url = NSURL.URLWithString(url)
urlRequest = NSURLRequest.requestWithURL url
        
@domParser.mainFrame.loadRequest(urlRequest)

フレームのロードが完了すると、Objective-C の場合は、webView:didFinishLoadForFrame: が呼ばれるらしい。Obj-C ではこれに対応するため、プロトコルを導入して〜とかしなければならなかったが、MacRuby では Ruby の動的性を生かして、ただ単に def webView(sender, didFinishLoadForFrame:frame) というようなメソッドを定義するだけでよいみたい。らくちん。

以下 didFinishLoadForFrame の中身

document = frame.DOMDocument
htmlDivElement = document.getElementById("DivMainResults")
if (htmlDivElement != nil) then
    html = "<!doctype html><html><head></head><body>#{htmlDivElement.innerHTML}</body></html>"
    mainFrame = browser.mainFrame
    mainFrame.loadHTMLString(html, baseURL:NSURL.URLWithString("/"))
end

ここまで来ると、あとは WebView の Frame から、DOMDocument が取得してこれるので、こいつで欲しい部分 (ここでは "DivMainResults" を id にもつ部分ツリー) を取得し、適当なコンテナ HTML に流し込み、結果表示先の WebView (ここでは browser 変数) に読み込ませる。

以上で、クリップボードを監視し、コピーされた単語を Web サイトにリクエストし、結果から必要な部分を取り出し表示する、ということが出来るようになった。ちなみにスクリーンショット:

f:id:ito_konnyaku:20130117031543j:plain

おわりに

Ruby で書けるようになっているとはいえ、Objective-C のシンタックスを置き換えたような感じなので、Cocoa などの知識が必要になる。また、MacRuby のドキュメントもあまり充実しているとは言えないため、Apple 本家の Objective-C ドキュメントを読む必要があり、Cocoa Objective-C プログラミングしたことないような人には若干ハードル高いかなーと感じた。ただ、本ツールでは 60 行ほどしかコード書いてないので、経験のあるような人は楽に GUI アプリ書けるだろうなーとか思いました。

iOS5 で MPMoviePlayer を使ってみる

iOS5 での音声、動画の再生が一番楽だと思われる MPMoviePlayer を使ってみる。サンプルとしては Apple で提供されている HTTP Live Streaming サンプルを使用。

MPMoviePlayerController を使うときは、Xcode で MediaPlayer.framework を使えるようにし、

#import <MediaPlayer/MediaPlayer.h>

としてインポートしてくる。

コード:

 NSURL* url = [[NSURL alloc] initWithString:@"http://devimages.apple.com/iphone/samples/bipbop/gear1/prog_index.m3u8"];
 _player = [[MPMoviePlayerController alloc] initWithContentURL: url];
 _player.view.frame = self.view.bounds;
 [self.view addSubview:_player.view];
 [_playerprepareToPlay];
 [_player play];

_player は property として宣言