投稿者「the-takeo」のアーカイブ

EvernoteにWebクリップするときの画像の扱い

EvernoteのWebクリップを酷使しているのだが、昔のノートを見直していると
画像が表示されないことがよくある。
どうやらネット上から元画像が削除されてしまっているようだ。

これが仕様なら諦める所だが、しかし、元画像が消えていてもEvernote上に残っている場合と残っていない場合があるようだ。
画像が相対パスで指定されているときは残らないようだ。

・・・ってのが昔調べた時の話だったんだけど、最近再検証した所、
どうも今は相対パスで指定されている画像でも問題なくEvernote上にクリップされるようだ。

確かめ方は以下のようにWeb版のEvernoteにアクセスし、画像を右クリックし、
「新しいタブで画像を開く」をクリックする。
そのアドレスが Evernte内ならOKだ。

2014-10-01_00_35_05

2014-10-01_00_35_42

まぁ、それでも一般にサムネは実画像より画質が悪いし、どうせならWebクリップするならサムネでなく、実画像をクリップしたい。
そんなときは以下のjavascriptをクリップ前に実行すると良い。

面白いように上からサムネ画像が実画像に置換される。
ついでに実画像へのリンクもなくなってすっきりする。

参考:EvernoteのWebクリップした画像は元サーバから消えると…orz

2014/10/5追記
Pocketからwebクリップすると画像がリンクになる場合があることを確認。
でも、どういう条件の画像がリンクになるのかは分からないんだよなぁ・・・

Crayon Syntax Highlighterが良いなぁという、そんな日記

WordPressでコードを書くとき、WP-Syntaxというプラグインを使っていた。
だけど、何故かWindows7のChromeで表示すると、C#のコードが上手く表示されない。
具体的には、コードの一部が左詰めになって、その上”.”以降は意図した位置に来たりしてちぐはぐになっている。
調べてみたらこのプラグイン、最終更新が2年前だった。ちょっと今のWordPressとは噛み合ってないのかもしれない。

折角Blogを再作成したので、プラグインも新しいものに変更した。
Crayon Syntax Highlighter
これもプラグインで検索すればすぐに出てきます。
WP-Syntaxより表示がしっかりしているし、コピーや表示変更などのメニューまで自動でつくようになっている。

↑みたいな奴が簡単にできるのだ。
WP-Syntaxとも互換性があり、WP-Syntax用に書いたコードもそのままCrayon Syntax Highlighter形式で表示される。

編集はこんな感じ↓

Crayon_Syntax_Highlighter_1

Crayon_Syntax_Highlighter_2

本当に簡単。素晴らC。


Skitchが思いの外使いやすいので無駄に使ってみた。

サーバー不具合で記事消失

サーバーの不具合のせいで、2014/7/10以降の記事が消えてしまった。

消えてしまった。

どうせ大した内容も無いからいいけど。

・・・って拗ねてたらGoogleキャッシュから消えた記事が見れることが分かった!
http://the-takeo.com/wp-content/uploads/2014/09/20140907.png

とりあえず、記事内容自体は取り戻せたので隙を見て復旧する予定。

まだドメイン関係やWORDPRESS関係で変な挙動になっているところがあるけど、
これらも少しずつ解消していこう。
ブロガーじゃなくて本当に良かった。

・・・ブロガーならバックアップはとっているか。反省。
定期バックアップとかできんのかね。

・追記(2014/09/08)
全記事復旧できたお。
どうせ大した内容じゃないけど。
DBの再構築とか色々やって勉強になった(小学生並みの感想)

Monoのアンインストール方法

さて、前回書いたように、Monoがインストール済みの状態ではHomebrewの導入が上手くいかない。
そこで、Monoのアンインストール方法を備忘のためにメモする。

以下のスクリプトをターミナルで実行する。
その際、管理者権限で実行する。
この「管理者権限で」というのが英語の読めない僕は気付かなかった。

ターミナルで管理者権限、即ちrootユーザーになるには、suコマンドを実行すればいい。
もし一度もrootユーザーになったことがないなら、以下の操作を行う。

  1. ターミナルでsudo passwd rootを実行する
  2. 「Changing password for root.New password:」と表示されるので、rootにログインするためのパスワードを設定する。勿論任意のパスワードで良い。
  3. 「Retype new password:」と表示されるので、同じパスワードを入力する。
  4. 「su -」を実行する。
  5. 先ほど設定したrootのパスワードを設定する。
  6. カーソル左の「$」が「#」に変わったら管理者権限への変更完了。

この状態で、上のスクリプトをコピペして実行すればMonoのアンインストールができる。


最近、プロジェクト管理ツールの「asana」が割と気に入っている。
使いやすい。その一点だけで素晴らしい。
しかも軽い。
仕事で使ってたけど、個人用でも使おうか考えている。

Homebrewを入れたという日記

今更というべきか、Macにパッケージ管理ソフトのHomebrewを入れてみた。
まぁ、一年前までは「そもそもパッケージ管理ソフトってなんだよ」って感じだったのにね。何だか不思議。
パッケージ管理ソフトってのは、簡単に言うとソフトのインストールやアンインストールを簡単にできる凄いやつ。
だいぶ違うけど、例えるならMacAppStoreみたいなもん。
だけど、CUI、つまり「インストールボタンをクリック・・・」とかじゃなくて、コマンドを打ち込んで操作するところがかなり違う。
例えば「brew install 超ウルトラすごいアプリ」って打ち込むと”超ウルトラすごいアプリ”がインストールされるのだ。
いちいち「アプリのHPに行って、インストーラをダウンロードして・・・」みたいなのが一気に省略できるのがいいところ。

で、そのHomebrewを導入するには以下の2条件が必要。

  1. Javaがインストールされている。
  2. Xcodeがインストールされている(正確には違うけど)

自体のインストールは凄く簡単。
HomebrewのHP(http://brew.sh/index_ja.html)に行き、画面最下部にあるコマンドをMacのターミナルに張り付ける。

・・・そんだけ!

この導入しやすさが流行っている秘訣なのかな。

インストール後はターミナルで”brew doctor”コマンドを実行することで、正しく動作するか確認することができる。
ちなみに、僕は何回やっても正しくインストールできませんでした。
理由はMono(C#や.NETをMacやLinux上で動かせるやつ)が入っていたから。
こいつをアンインストールすることでHomebrewを正しくインストール出来ました。
(実はそれに少し苦労したんだけど、それは別の機会に)
ちなみに、Mono自体はHomebrewからインストールすることは可能です。
なので、Monoをアンインストール→Homebrewをインストール→HomebrewからMonoをインストール、というプロセスでHomebrewとMonoの共存は可能です。

・・・まぁ、導入したところで必要なアプリはあらかたもう入っているので、使う機会無いんだけどね。
今度クリーンインストールしたときにフル活用しよう。

一時帰国

夏休みということで、日本に一週間だけ帰国することが出来た。
免許更新とか健康診断とか、やるべきことは多いけど、日本がやっぱり一番です。
こんなに過ごしやすい国はないと思う。
小売店の圧倒的品揃えや、痒いところに手が届くサービスから、少し陰鬱な空気とか、寂れた住宅街の雰囲気まで、全てが大好きだ。
シンガポールは確かに良い国だ。
だけど、あの常に肩肘張ったような、物語の人物のような、あの感覚が僕は好きになれない。
リラックスしているときですら、リラックスしている自分を演出している感がある。
・・・いや、俺が捻くれた感じ方をしているだけなんだけど。
あとラーメンが旨い。シンガポールのラーメンも最近美味しいと感じていたけど、やっぱりレベルが違う。
日本いた時は「普通じゃん」程度の感覚だったのにね。不思議。
まとまった時間が取れれば、もっとちゃんと書こう。
とりあえず、更新停止防止のため、投稿。

Macでバッチファイル的なものを作成する

仕事上、Windowsのbatファイルを作成することがよくある。
パソコンをまともに触るまではコマンドラインすら使いもしなかったが、
意外といろんな操作を自動化できて楽しい。
で、batファイル的なものをMacでも作ろうかと思ったが、意外と落とし穴があったのでメモ。


  1. シェルスクリプトで実行内容をテキストに記述
    以下の様なスクリプトを任意のテキストエディタで記述する。

    このとき、改行コードをUNIX(LF)にする。
    そのため、テキストエディタは何でも良いが、改行コードを設定できることにすること。
    記述したら、このファイルの拡張子を”.command”として保存する。
  2. ターミナルからコマンドファイルの実行権限を付ける
    上記のファイルをそのまま実行しようとしても、「適切なアクセス権限がないため実行できません。」となり、実行できません。
    そこで、ファイルを実行できるようにアクセス権を設定します。

    1. ターミナルを開き、先ほど作成したファイルを保存したディレクトリに移動する。
    2. 以下のコマンドを実行し、実行権限を付ける。

後は.commandファイルを実行するだけでターミナルが開かれ、記述した操作内容が実行される。
実行後、ターミナル画面がそのまま残ると味が悪いので、終了後画面が閉じるようにターミナルを設定すると良い。

  1. ターミナルから、「ターミナル」→「環境設定」を開く
  2. 「設定」→「シェル」タブで、「シェルの終了時」を「シェルが正常に終了した場合は閉じる」にする

以上。
僕はC#で作ったファイル整理系コンソールアプリをmonoで実行させるのによく使っています。
コマンド内容は以下の通り。


来月には帰国できる・・・はず。

C#でEvernoteアプリを作る

Evernoteは言わずとしてたクラウドメモツールだ。
使い道は人それぞれだが、僕はwebクリップでプログラミング関連のページを保存したり、
2chで面白いと思ったスレやレスを保存したり、
画像スレの画像をページごと保存したり、
ロクでもない使い方をしている。
で、EvernoteはAPIを公開しており、これを使えば誰でもEvernote関連アプリケーションが作成できる。
C#でも公開されており、C#しか使わない僕にも使えた。
テキスト投稿アプリならすぐに作れてしまう程分かりやすい仕組みになっている。
何より日本語化されているのがいい。リファレンスは英語だけど。
備忘の為、0からの使い方を以下にまとめた。

  1. Developer登録をする
    1. https://dev.evernote.com/intl/jp/に行き、「APIを使いはじめる」をクリックする。
    2. APIドキュメントのページが表示されるので、「APIキーを取得」をクリックする。
    3. 申し込みフォームが表示されるので、必要事項を入力する。
      (API権限は作りたいアプリ種類によって選択する。投稿アプリならベーシックアクセスでいいし、既存Noteの編集を行うならフルアクセスが必要。
      とりあえず試すだけならフルアクセスにしておけばいいと思う)
    4. コンシューマーキーとコンシューマーシークレットが発行されるので、メモしておく。
  2. SDKを取得する
    1. APIドキュメントでC#の「SDKをインストール」をクリックする。
    2. Githubのページがでてくるので、右下の「Download ZIP」をクリックし、ソースコードを取得する。
      (勿論クローンでもいいです。お好きな方で)
  3. EvernoteSandbox(開発環境)のアカウントを取得する
    1. EvernoteのAPIはいきなり通常のアカウントに対しては使えず、
      まず開発環境内で動作検証をして、OKだと思ったら本番環境での使用許可を得る、という形になっています。
      開発環境はEvernote社が提供しているので、そのアカウントを取得します。
    2. https://sandbox.evernote.com/で「アカウントを作成」する。
      以下、手順にしたがってアカウントを作成してください。
      このときのアカウントとパスワードは自分のEvernoteアカウントとは全く無関係なものでOKです。
  4. デベロッパトークンを取得する
    1. いちいち自分の環境に対してユーザーIDとパスワードを入力して認証するのは
      面倒ですが、デベロッパトークンを用いることでその作業を省略できます。
    2. ここのページ中段の「サンドボックス用のデベロッパトークンを取得」をクリックする。
    3. 先程取得したSandboxのアカウントとパスワードを入力する。
    4. 「Creat a developer token」とクリックし、表示されたデベロッパトークンをメモする。
  5. Sampleアプリを動かしてみる
    1. 2でダウンロードしたSDKをZIPなら展開し、sample→client内のEvernote.slnをVisualStudioで開く。
    2. SampleAppプロジェクト内のEDAMTest.csを開く。これがサンプルアプリのコードです。
    3. 40行あたりにauthTokenが定義されているので、先程取得したデベロッパトークンに設定してください。
    4. VisualStudio上で実行してください。上手く実行されればsandbox環境内に新規ノートが作成されます。

後はソースを眺めてAPIの仕組みを大まかに把握し、色々変更してみたりして弄ってみてください。
なお、自分のアプリでAPIを利用する場合は、EDAMプロジェクトをビルドしてできた「Evernote.dll」と「Thrift.dll」をコピーし、アプリのプロジェクトのの参照設定に追加してください。
細かい使い方やリファレンスは他のページにまとまっていますので、そちらを参照したほうが良いと思います。
ちなみに、地味に躓くのが認証する所だと思います。
僕は下記のソースを参考にしています。
参考というか、利用させてもらっています。
MITライセンスだからね。本当に感謝しています。
https://github.com/matchy2/EvernoteOAuth
Sandbox上の検証が十分に完了したら、プロダクション用のデベロッパトークンを使って自分の本アカウントEvernoteに使ってもいいし、アクティベートしてコンシューマーキーをプロダクト環境で利用可能にして、一般公開してもいいと思う。
僕が作ったAppも一応このサイトに置いてあります。
クソコードなので中身はあまり見せられません。

InvokeでFormをCloseして、その後すぐに同じFormインスタンスを生成するときの注意点

タイトルが長くなった。
ちなみに検証できないので内容的に間違っているかもしれません。
解決方法も最善解ではないです。
完全に自分の覚え書き用の記事です。

おおまかに言うと、上記のようなコードを実装していた。
InvokeしてるのはこのメソッドがUIスレッドでない別スレッドで実行されるからです。
簡単に言うと「今表示されているSampleFormを閉じて、初期化して再度表示する」という実行内容。

で、これがいざ実行するとハングすることがある。
困ったのは、100%でなく、起こったり起こらなかったりするところである。

form.Show()の直前でブレイクしてデバッグすると、どうやらここでformがDisposeされていることがあるということが分かった。
しかし、// (中略2)や// (中略3)のどこにもformをDisposeする要素がない。
より詳細に見ようと、// (中略2)にブレイクポイントを置いてデバッグしたところ、問題が一切発生しなくなった。

しばらく頭を捻っていたが、ようやく尤もらしい仮説が見つかった。

InvokeされたCloseによるDispose処理が、「form=new SampleForm()」後に実行され、
折角初期化したformがDisposeされてしまった。

シナリオはこうだ。

1)(処理スレッド)CloseをUIスレッドに託す
2)(UIスレッド)formをCloseする
3)(処理スレッド)処理スレッドformを初期化する
4)(UIスレッド)Closeしたことだし、formをDisposeする
5)(処理スレッド)formをShowする

formはDisposeされてるから無理ですよ〜だ。

4が3と5の間に起こると本件が発生する。
そのタイミングは環境の状態によるので、問題が発生したりしなかったりした訳だ。

で、以下のように1行追加して問題は発生しなくなった。

一度たまっている処理(Close含む、ってか多分Closeしかない)を全て実行させればいいのだ。
Mutexを使う等して排他制御をした方が正確だが、バグの温床に成りかねないのでこの方法にした。
ちょっと不安ではあるけど、これで問題なさそうならこれで行こうと思う。

昔「おまじないだ」と言われたApplication.DoEvents()を使うことになるとはなぁ。
ネットで調べたらあまり勧められない方法らしいけど、そこまで必死に直す箇所じゃないからね。仕方ないね。

DataViewでRowFilterを設定する場合の注意点

DataViewはDataTableと似たようなクラスだが、
インスタンス生成時に既にインデックスを貼ってくれていたり、
まぁ色んな違いがある(投げやり)。

で、最近いじっていたあるコードがある。

DataViewにRowFilterを設定し、その後の処理結果によってまた同じ操作を繰り返すというものだ。
(実際のコード上は無限ループにならないようになっています。念のため)
これがやけに時間がかかる。
原因はRowFilterがRowFilterを何度も行ったことだった。

なぜなら理由は単純で、RowFilterが実行された場合、DataViewは内部的にインデックスを設定してしまっているのだ。
インデックスを設定するために毎回全データを取得しに行っているわけで、これでは大変時間がかかる。

で、幸い「// (dvを使った実行内容)」の内容をRowFilterでなく、FindRowsに置き換えることが可能だったので、それでひとまず解決した。
FindRowsメソッドはインデックスを再設定しないのだ。
(参考:http://msdn.microsoft.com/ja-jp/library/bb669089(v=vs.110).aspx

RowFilterで遅くなっている可能性を全く考えておらず、分かるのに時間がかかった。
ぱっと見、プロパティ設定してるだけに見えるからね、仕方ないね。

・・・修正したはいいけど、割と条件分岐が複雑なメソッドなので、テストに時間かかりそう。
(現に実装終わった後にバグを指摘されまくった)