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

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

タグ:plugin

人気のテキストエディタである 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

 

ElasticSearch で英語以外のテキストを使った検索エンジンを実装しようとすると、多くの場合 ICU(International Components for Unicode) というプラグインを使うことになります。特に日本語を扱う場合は kumoroji プラグインとセットで使うことが多いようですが、日本語文字列を正規化してフィルタリングをかける場合のデファクトスタンダードになっている組み合わせだと思います。

この ICU プラグインを ElasticSearch に導入する方法は ICU プラグインのホームページに記載されています:
https://github.com/elastic/elasticsearch-analysis-icu


具体的な導入方法は上記ページ内に記述されているように、コマンドラインから
# bin/plugin -install elasticsearch/elasticsearch-analysis-icu/(ICU のバージョン番号)

と入力・・・ だと思っていました。ところがこの方法は ElasticSearch のバージョンが 1.x までの頃の話でした:
2016111801


現在、多くの人が使っている ElasticSearch のバージョンは 2.x 以上だと思っています(2016/Nov/18 時点の最新バージョンは 5.0)。では ElasticSearch 2.x で ICU を導入するにはどのようにすればいいのでしょうか?

答はこれでした。かなりシンプルになりました:
# bin/plugin -install analysis-icu

これ、公式のどこかに書いてないのかな・・・

世のノーツ開発者の興味が XPages に寄っている中で、1世代前の技術情報になることをご容赦ください(苦笑)。

久しぶりに触ったノーツに、久しぶりにプラグインをインストールしようとしてハマりました。何言っても言い訳になることはわかった上で、でもこの業界で1年半のブランクは大きいようです(苦笑)。


ノーツ(IBM Notes) はバージョン8から Eclipse RCP(Rich Client Platform) をベースとしたクライアントに生まれ変わり、Eclipse 向けに提供されているプラグインをノーツにもインストールできるようになりました。そもそも Eclipse は開発環境なので、世に出ているプラグインは開発環境向けのものが多いです。それもあって、プラグインの互換性は100%ではないのですが、Eclipse のプラグイン開発技術やスキルを使ってノーツの機能拡張もできるようになった、というものでした。

Eclipse の場合、プラグインをインストールしようとするとメニューの Help から Install New Software を選んで・・という手順になります:
2015030101


ノーツの場合はその方法からして異なるのですが、実はそれ以前に「そもそもプラグインインストールをメニューに表示するための準備」が必要でした。

それが
 (ノーツをインストールしたディレクトリ)/framework/rcp/plugin_customization.ini ファイルに
 com.ibm.notes.branding/enable.update.ui=true の一行を追加する
というもの。これをしてノーツを再起動すると、メニューの File - Application からインストールができるようになる・・・ はずだったのです。

でも試してみたらこんな感じ。File - Application までは表示されるのですが、その先にインストールの選択肢がありません:
2015030102


あれ?これは何?? と驚きましたが、どうやらノーツのバージョン9からこの部分の仕様が変更されていた模様です。詳しくはこちらの Technote にかかれていましたが、この設定に加えてランタイム設定の com.ibm.notes.branding.prefs ファイルから一行削除する必要がありそうでした:
[ファイル] - [アプリケーション] - [インストール] メニューが plugin_customization.ini ファイルで設定しても表示されない


ここまでの設定をしてノーツを再起動すると、無事にインストールメニューまでが表示されるようになりました:
2015030103


うーん、しばらく離れていて気づきませんでした。いつの間に・・・

この方法で UpdateSite の URL を指定して Eclipse プラグインをインストールすることができます。

またノーツ用の拡張機能を使って Eclipse プラグインを開発することもできますが、その手順の解説がどこかにないかなあ、と探していたら、こんなページを見つけてしまいました。今となっては懐かしくもあり、恥ずかしくもある技術解説ページです:
Lotus Notes 8 プラグインでグラフィックコンテキストを利用する



で、個人的にこんなの(画面右)を作ってたりします:
2015030104

このプラグインはいずれ公開したいとずっと思っていて、でもそれには公開 Domino サーバーが必要で、さてどうしたものか・・・と悩んでいたのですが、最近になって IBM Bluemix を使う方法を思いつきました。いずれ公開しますのでお楽しみに。なお、その際はこのページに書かれた設定も必要になると思うので、その時にまた参照してください。




WordPress は世界中の多くのサイトで使われているオープンソースコンテンツ管理システムです。

ブログシステムとして使っている人も多いと思いますが、ウェブサイトのコンテンツ管理システムとしてもよく使われています。そしてユーザーが多いこととオープンソースであることからコミュニティも形成され、WordPress 自体をさらに便利にするプラグインも多く開発され、公開されています。

先日(2015/Feb/25)、WordPress の Twitter プラグインが公開されました。しかもこれ、ツイッター社が作った「純正プラグイン」です。 面白そうなので試してみました。


以下にその手順を紹介しますが、実際に試してみるには管理者権限でアクセスできる WordPress 環境が必要です。もし新たに作成する必要があれば、IBM Bluemix を使うことで無料の WordPress サーバー環境を構築することができます。詳しくはこちらの紹介記事も参照ください:
IBM Bluemix で無料の WordPress 環境を構築する


管理者として使える WordPress 環境が用意できたら実際に Twitter プラグインを導入して使ってみます。まずは管理者ページ(http://(WordPress サーバー)/wp-admin/)にログインし、「プラグイン」 - 「新規追加」 で "twitter" と入力して検索します。すると多くの twitter 関連プラグインが見つかりますが、その中に作成者が "Twitter" となっている純正プラグインがるので、それを選んで「いますぐインストール」ボタンをクリックします:
2015022601


Twitter プラグインがインストールされます。完了したら「プラグインを有効化」をクリックしてサイト内で有効にします:
2015022602


次に有効にしたプラグインの動作環境設定を行います。「プラグイン」パネルを選ぶと、インストール済みプラグインの一覧が表示されます。その中に「Twitter」が追加できているはずなので、その「設定」をクリックします:
2015022603


Twitter プラグインの設定が表示されます。ツイートボタンをクリックした時の動作として特定の Twitter ユーザーへのメンションを行う設定や、ツイートボタンの表示位置などを指定できます。最後に保存します:
2015022604


これで Twitter プラグインが有効になって、設定した内容で動くはずです。試しにこの WordPress サイト内のツイートを1つ表示すると、Twitter の「ツイート」ボタンが追加されているはずです:
2015022605


このボタンをクリックすると、このページへのリンクが付与されたツイートが、エントリタイトルと併せて表示されます。またこの例では @dotnsf (僕です)ユーザーへのメンションが付与されるようになっています:
2015022606


最後にこのツイートテキストの内容をカスタマイズする方法も紹介します。管理者権限でこのツイートの編集画面(あるいは新規投稿時の作成画面)の下の方に、Twitter カスタムテキストの設定が追加されているはずです。この中のテキストを変更したり、あるいはハッシュタグを付けて保存します:
2015022607


この状態で先ほどのツイートボタンをクリックすると、今度はツイート内容が指定したテキストになっているはずです。またハッシュタグを指定していた場合はその内容も含まれているはずです:
2015022608


シンプルな内容ですが、WordPress のコンテンツが簡単に Twitter ボタンと連携できるようになっていると思います。ブログコンテンツをカスタマイズしてツイートしたい(させたい)時に便利です。


なお、管理者画面のプラグイン一覧の "Twitter" で「編集」をクリックすると、このプラグインの PHP ソースコードが確認できます。ツイッター社の純正 PHP コードが目にできるのは珍しい機会なので、書き方とか興味ある人はこちらも見ておくといいかも:
2015022609












 

最近のマイブームの1つになっている、全文検索エンジン ElasticSearch に MySQL のデータを取り込んで、MySQL データベースの全文検索エンジンとして ElasticSearch を使う手順の紹介です。
2014070401


まず検索エンジンである ElasticSearch を導入します。日本語形態素解析エンジンである Kuromoji まで含めてのインストール手順を別エントリで紹介しているので、こちらを参照ください:
ElasticSearch に Kuromoji プラグインを導入する


また取り込み先である MySQL サーバーについても環境は構築済みであると仮定します。こちらの構築手順についても、こちらのエントリを参照ください:
CentOS に MySQL をインストール/セットアップする

なお、自分個人的には MySQL ではなく MariaDB を使って同じことをできているので、以下の内容に関しては MariaDB でも同様に可能だと思っています。


さて、ElasticSearch に MySQL データを取り込むための準備として ElasticSearch 自体のインストール後に以下のステップを行う必要があります:
1. (MySQL クライアントと)JDBC ドライバの導入
2. JDBC River プラグインのインストール


最終的には ElasticSearch の River プラグインと呼ばれる拡張機能を使って MySQL からのデータ取り込みを行います。このプラグインの動作に必要な MySQL JDBC ドライバを先にインストールしておく、というステップになります。


まず、これは必須ではありませんが、あると確認に便利なので MySQL のクライアント環境を ElasticSearch サーバー内に構築しておきます。MySQL サーバーに接続する機能があればいいので、MySQL サーバー機能は不要で、クライアント機能だけが必要、ということになります。もし MySQL サーバーと ElasticSearch サーバーが同じサーバーだとすると、既に MySQL クライアント環境は導入済みだと思うので、インストールは不要です。 MySQL クライアントが導入されていない場合は以下のコマンドで MySQL クライアントをインストールします:
# yum install mysql
# vi /etc/my.cnf
  :
(以下の2行を追加)
[mysql]
default-character-set=utf8

MySQL クライアントが導入できた所で、取り込み元の MySQL サーバーへ接続してみます。仮に今回取り込むデータの内容が以下であると仮定します:
 MySQL サーバー: mysql.mylocal.com
 ユーザー名: username
 パスワード: password
 データベース名: mydb
 取り込む内容: samples テーブル


実際に MySQL クライアントで目的のデータベースにアクセスしてみます。ここまでが出来るようであればファイアウォールなども含めて接続準備ができているといえます:
# mysql -h mysql.mylocal.com -u username -ppassword mydb
> select * from samples;
:
:
(samples テーブルの内容)
:
: > quit


次に MySQL サーバーへ Java 環境から接続するための JDBC ドライバー(MySQL Connector/J)を導入します。ドライバー自体はこちらのサイトからダウンロードできます:
MySQL :: Download Connector/J 


ダウンロードしたファイルを展開して JAR ファイルを取り出し、/usr/share/java にコピーします:
# unzip mysql-connector-java-5.1.30.zip
# cd mysql-connector-java-5.1.30
# cp mysql-connector-java-5.1.30-bin.jar /usr/share/java

環境変数 CLASSPATH に、この JAR ファイルを追加します:
# vi /etc/bashrc
  :
(以下の1行を追加)
export CLASSPATH=$CLASSPATH:/usr/share/java/mysql-connector-java-5.1.30-bin.jar
 

# source /etc/bashrc

JDBC ドライバの準備が出来た所で River プラグインをインストールします。リポジトリを確認したところ、2014/07/01 時点での最新バージョンは 1.2.1.1 だったので、このバージョンを指定して導入します:
# /usr/share/elasticsearch/bin/plugin --install jdbc --url http://xbib.org/repository/org/xbib/elasticsearch/plugin/elasticsearch-river-jdbc/1.2.1.1/elasticsearch-river-jdbc-1.2.1.1-plugin.zip
# cp /usr/share/java/mysql-connector-java-5.1.30-bin.jar /usr/share/elasticsearch/plugins/jdbc/

これで必要なソフトウェアは揃いました。では実際に MySQL からデータを取り込んでみましょう

まず ElasticSearch 側に kuromoji を使った検索インデックス(kuromoji_sample)を作成します。インデックスの作成については別エントリでも紹介しましたが、まだこの内容を実行していない場合は以下のコマンドを実行します(コマンドは黒字部分で、青字はレスポンスを表しています):
# curl -XPUT http://localhost:9200/kuromoji_sample -d '{ "index": { "analysis": { "tokenizer": { "kuromoji_user_dict" : { "type":"kuromoji_tokenizer" } }, "analyzer": { "analyzer": { "type":"custom", "tokenizer": "kuromoji_user_dict" } } } } }'
{"acknowledged":true}

次に River を使って、作成した kuromoji_sample インデックスに MySQL データベースサーバーからデータを取り込みます:
# curl -XPUT http://localhost:9200/_river/my_jdbc_river/_meta -d '{ "type": "jdbc", "jdbc": { "url": "jdbc:mysql://mysql.mylocal.com:3306/mydb", "user": "username", "password": "password", "sql": "select * from samples", "index": "kuromoji_sample", "type": "samples" } }'
{"_index": "_river", "_type": "my_jdbc_river", "_id": "_meta", "_version": 1, "created": true}

上記入力パラメータ(JSON)の中で選択(select)の SQL を発行しています。この SQL の実行結果が ElasticSearch に取り込まれることになります。

取り込みができたら、最後に検索してみます。この例では取り込んだデータの name フィールドに「ほげほげ」が含まれているデータを検索しています:
# curl -XPOST http://localhost:9200/kuromoji_sample/_search?pretty -d '{ "query": { "query_string": { "query": "name:ほげほげ" } } }'
{
  "took" : 2,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "failed" : 0
  },
  "hits" : {
    "total" : 29,
    "max_score" : 3.687642,
    "hits" : [ {
      "_index" : "kuromoji_sample",
      "_id" : "XXXXXXXXXXXXXX",
      "_score" : 3.687642,
      "_source":{"id":"1234","name":"ほげほげ"}
    }, {
      "_index" : "kuromoji_sample",
        :
    } ]
  }
}

こんな感じで実現できました。

MySQL の like 節を使った単純検索をしていた頃と比べると、以前は localhost 内の MySQL に対して検索していたのでネットワークによる遅延はほとんどなかったはずで、今回作ってみた環境はリモートの ElasticSearch 環境にアクセスしているので、ネットワークの遅延影響がでるはずです。

にも関わらず、検索パフォーマンスは 10 倍程度になりました。これはでかい!

ElasticSearch の検索パターンやその API 実行方法についてはいずれまたプログに書く予定です。


 

このページのトップヘ