まだプログラマーですが何か?

プログラマーネタとアスリートネタ中心。たまに作成したウェブサービス関連の話も http://twitter.com/dotnsf

タグ:extension

人気のテキストエディタである Visual Studio Code(以下 "VSCode")の機能を独自に拡張するプラグインの開発に挑戦してみました。以下で紹介するプラグインの開発は主にこのページにかかれている内容を参照し、参考にさせていただきました。ありがとうございます:
Visual Studio Codeの拡張機能を一通り触って自分用に公開するまで


作った拡張機能は MOTD(Manhole of this day) といいます:
https://marketplace.visualstudio.com/items?itemName=dotnsf.manholeofthisday

2020062305


機能は名前そのままですが、拙作マンホールマップの機能の1つである「今日のマンホール」を VSCode 内に表示する、というマンホーラー向けのものです。

VSCode にこのプラグインをインストールするには左ペインから「拡張機能」を選ぶか、Ctrl + Shift + X を押して拡張機能画面に移動し、検索バーに "manholeofthisday" と入力します("manholeof" あたりまで入力すると、検索候補が一つになります)。そして「インストール」と書かれた箇所をクリックしてインストールします:
2020062301


インストール後、実際に MOTD 機能を利用する場合は Ctrl + Shift + P でコマンドパレットを開き、このパレットに "MOTD" と入力してコマンドを検索し、最後に見つかった MOTD 部分をクリックします:
2020062302


MOTD コマンドを実行した日(月&日)のマンホールがマンホールマップの「本日のマンホール」に記録されて存在していた場合は VSCode 内の新しいタブが一つ追加され、その中で「本日のマンホール」画像と説明が表示されます。なおこの機能の実現には Webview API を使っています:
2020062303


画像部分をクリックすると、ブラウザで該当マンホールのマンホールマップ内ページが開き、より詳しい情報を参照することができる、というものです:
2020062304



この MOTD プラグインのソースコードはこちらで公開しています。開発言語として TypeScript を選ぶこともできましたが、今回は JavaScript で開発しました。この手軽さもハードル低くていいですね:
https://github.com/dotnsf/manholeofthisday

 

facebook を使っていると、「今日は○○○さんの誕生日です!」というお知らせが届きますよね:
2017062101


ある程度以上の繋がりがあると、体感的にはほぼ毎日のようにこの機能を目にすることになります。もちろんちゃんと心の籠もったメッセージを作って、思い出の画像も用意して、・・・という人もいますが、中には「メッセージ考えるのも面倒くさい、そんなにお世話になってるわけでもないし、ってかこいつ誰だっけ?どんなメッセージを送るのがいいのかなあ」と頭を悩ませることもあります。そんなあなたの大切な時間を節約する Chrome プラグインを作ってみました。

このプラグインを Chrome にインストールして有効にすると、facebook の誕生日ページに移動して、そこに今日が誕生日でまだバースデーメッセージを送っていない人がいると、自動的に(あらかじめ用意した)メッセージを入力してくれます(自動投稿まではしません)。そのままで良ければ後は投稿するだけ、「この人にはちゃんとメッセージを書きたいなあ」という場合はそこから編集することもできます:
2017062100

(↑こんな感じ。自動的にバースデーメッセージが入力された状態になります)


プラグイン自体は github 上に公開しておきました:
https://github.com/dotnsf/fb_birthday_extension


上記ページから git clone するかダウンロード&展開して、ローカルシステム上に以下の3つのファイルが存在しているディレクトリを用意します:
2017062102


この中の script.js というファイルが拡張機能の本体となる部分です。中身は結構シンプルにこんな感じ:
var birthday_msg = 'ハッピーハッピーバースデー♪';

$(function(){
 $("#events_birthday_view div:eq(0) ul li ._42ef ._6a ._6b:eq(1) div div:eq(1) textarea").each(function(){
  var textarea = $(this);
  textarea.val( birthday_msg );
 });
});

1行目の birthday_msg 変数がバースデーメッセージです。必要に応じてこの内容を書き換えて使ってください。


では実際にインストールしてみます。Chrome を起動して拡張機能の画面(右上のメニューから「その他のツール」-「拡張機能」)に移動します:
2017062106


現在インストール済みの Chrome 拡張の一覧が表示されます。ここで「デベロッパーモード」が有効になっていることを確認し、「パッケージ化されていない拡張機能を読み込む」をクリックします:
2017062103


先程ダウンロードした3つの拡張用ファイルがあるディレクトリを指定します:
2017062104


すると "FB Birthdah" という名前の、この拡張機能が導入されます。「有効」にチェックを入れると、実際に facebook の誕生日ページで動くようになります。なお、導入後に script.js の中身を書き換えた場合は、この画面内の「リロード」をクリックすると、変更が反映されるようになります:
2017062105


これで上記で紹介したような心の籠もっていないバースデーメッセージを自動作成することができるようになっている、はず:
2017062101


※このプラグインはあくまで誕生日ページを参照した時に動作するもので、↓こんな感じのダイアログで出た場合は動いてくれません、あしからず:
20170621


画像(特に写真)ファイルの中には、その写真を撮影した時の日時やカメラの種類、場所といった付属情報が含まれていることがあります。

それらのメタ情報を特定のフォーマットに従って画像に埋め込むことで、画像ファイルの中に、目に見えない形で撮影日時や撮影場所といった情報を含めて保存することができるようになります。

この「特定のフォーマット」のことを EXIF(EXchangable Image Format) と定義され、「イグジフ」などの略称で呼ばれています。

この Exif 情報をウェブブラウザから参照することもできます。多くはプラグインやアドオンなどの拡張機能として提供されています。私が個人的によく使っているのが、FireFox の Exif Viewer という拡張機能です:

https://addons.mozilla.org/ja/firefox/addon/exif-viewer/

2017030801


上記サイトから「Firefox へ追加」ボタンをクリックして FireFox にインストールし、FireFox を再起動すると有効になります。

使い方は簡単で、FireFox を利用中に Exif 情報を参照したい画像があったら、その画像の上で右クリックして「画像の EXIF データを表示」を選択、です(ちなみにこの画像は先日のベルサール秋葉原でのイベントで僕が撮影したものです):
2017030802


ウィンドウがポップアップして、選択した画像の Exif 情報が確認できます。画像に Exif 情報が含まれていた場合はこの中に表示されます。緯度(北緯 35.701442度)と経度(東経 139.770919度)が表示されていることがわかります:
2017030803


ちなみにこの場所を Google マップで開いてみると、見事にベルサール秋葉原・・・ではなく、少しズレがありますが(苦笑)、まあほぼ正解でした:
2017030804



つまり写真の中に位置などの情報が含まれていると、この方法で場所が特定できてしまうわけでもあります。まあ最近の SNS では「アップロードした画像の Exif は自動的に削除される」ような仕様になっているものが多いのですが、ネットに画像などをアップロードする際には気をつけましょう。


ウェブブラウザである Chrome の機能を拡張する Chrome extension を作ってみます。今回は試しに
 Chrome でアマゾンの商品ページを見ている時に、そのページ内の ASIN コードを取り出して表示する
というシンプルな機能を実装してみます。

この Chrome 拡張機能の開発方法に関してはこちらに公式ドキュメントがあります。が、Chrome 自身のバージョンアップにともなって機能変更が加わり、それが混乱を招いてしまっている側面はあると思っています。今回紹介する内容はとりあえず 2016/Jun/23 時点では動くことを確認していますが、将来的な保証はないことを最初にお断りしておきます。

今回用意するファイルは次の3つです:
ファイル名用途・コメント
jquery-3.0.0.min.jsjQuery ライブラリ。ここから最新版をダウンロードし、manifest.json 内にファイル名を記述する
manifest.json拡張機能の定義ファイル
script.js拡張機能の実装ファイル


まず jQuery の最新版ライブラリを使います。jQuery のダウンロードページから最新バージョン(今回の例では 3.0.0)をダウンロードします。

次に定義ファイルである manifest.json です。Chrome 拡張機能を作る際に必須の JSON ファイルで、Chrome はこのファイルの中に記述されている通りに拡張されます。今回は以下の様な内容にします:
{
  "name": "AmazonASIN",
  "version": "0.0.1",
  "manifest_version": 2,
  "description": "Amazon商品ページからASINコードを取り出す拡張",
  "content_scripts": [
    {
      "matches": ["http://www.amazon.co.jp/*","https://www.amazon.co.jp/*"],
      "js": ["jquery-3.0.0.min.js","script.js"]
    }
  ]
}

この中では以下の様な指定を行っています:
  • 拡張の名前(name)は "AmazonASIN"
  • 拡張のバージョン(versoin)は 0.0.1
  • マニフェストのバージョン(manifest_version)は2(固定)
  • description に拡張の説明を記述
  • content_script 内にスクリプトの条件を指定
  • このスクリプトは http(s)://www.amazon.co.jp/ 内のページを参照している時だけ動く
  • 動くファイルは前述の jquery-3.0.0.min.js と後述の script.js

簡単に言うと、アマゾン(www.amazon.co.jp)のページを参照している時に script.js が動く、という指定をしています(jquery-3.0.0.min.js は script.js 内で利用しているのでここに記述しています)。

そして今回紹介する拡張機能の本体となるのが script.js です。この内容は以下のとおりです:
$(function(){
 $(".col2 .pdTab tr:first").each(function(){
  var tr = $(this);
  var td1 = tr.children('td:first');
  if( td1.html() == "ASIN" ){
    var td2 = tr.children('td:nth-child(2)');
    var asin = td2.html();
    window.prompt( "ASIN", asin );
  }
 });
});

jQuery にある程度詳しい人であれば簡単に理解できそうなほどシンプルな内容ですが、中身を一応紹介します。

まず最初に、自動化したい作業はこんな感じです:
  1. アマゾンの商品ページを開いたら、
  2. 「登録情報」の「ASIN」と書かれた箇所(下図参照)を探して、
  3. その横の ASIN 番号を取り出して表示する

2016062301

↑この機能、アフィリエイターに需要ありますかね・・・


そしてこのアマゾン商品ページの HTML ソースを見ると、『「登録情報」の「ASIN」と書かれた箇所』というのが、『col2 クラスを持った div パート内の、pdTab クラスを持った div 内のテーブルの、最初の tr パート』であることがわかります:

2016062302


この tr の2番目の td に目的の ASIN 番号が書かれているのでこれを取り出すのが目的です。というわけで、上記の script.js 内では以下の様な処理を記述しています:
  • Amazon のページでのみ以下を実行する(manifest.json で指定済み)
  • ページが全て読み込まれた後に以下を実行
  • col2 クラス以下の pdTab クラスの更に下にあるテーブルの最初の1行(最初のtr)を取り出す
  • 取り出した tr 内の1つ目の td を取り出し、その中に "ASIN" と書かれていることを確認する
  • 確認できたら tr の2つ目の td (ここに ASIN 番号がある)を取り出して、その HTML 文字列を取り出す
  • 取り出した ASIN 番号を画面に表示する

これで処理の記述はできたので、上記3つのファイルを全て同じフォルダ(下図では c:\tmp\amazon_extension)内に保存します:
2016062303


作成した Chrome 拡張はデベロッパーモードの Chrome 内に読み込ませて利用することができます。Chrome を起動後、右上のメニューボタンから 「その他のツール」-「拡張機能」 を選択します:
2016062304


Chrome 拡張機能のメニューが表示されたら、右上の「デベロッパーモード」にチェックを入れます。これでデベロッパーモードになったので、更に「パッケージ化されていない拡張機能を読み込む」ボタンをクリックします:
2016062305


先程作成した3つのファイルを格納したフォルダ(上記の例では C:\tmp\amazon_extension\)を指定して拡張機能を読み込みます:
2016062306


拡張機能にエラーがなければ正しく読み込まれ、拡張機能一覧に表示されます。「有効」にチェックが入っていることを確認してください(チェックを外すと、この拡張機能は動きません。またその右のゴミ箱アイコンをクリックすることで拡張機能を Chrome から削除することもできます):
2016062307


では改めてアマゾンの商品ページを見てみましょう。例えばこのページを参照してみると、、
https://www.amazon.co.jp/gp/product/B014CGROJW/


商品ページがロードされた後に以下の様なダイアログが表示され、ASIN コードが取り出されたことが確認できるはずです(必要であれば、ここからコピーできます):
2016062308


Chrome 拡張機能のごくシンプルな例ですが、こんな感じで作れます。実体はクライアントサイドの JavaScript ですが、クロスサイトスクリプティングの制約を受けることなく AJAX が実行できたりするので、この中で外部連携も含めた様々な処理を記述できます。例えばここで紹介されているサンプルでは Chrome 拡張から Watson API を実行していたりします:
女優・ディベロッパー池澤あやかさんが作成したアプリとは? |Bluemix Developers Lounge


このページのトップヘ