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

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

タグ:node

IBM Cloud からはオープンソースのブロックチェーン基盤である Hyperledger Fabric をベースとしたマネージドなブロックチェーン環境が提供されています。この 3/21 からは Starter Membership Plan という、名前の通りに小規模向けの比較的安価なプランも提供されるようになりました。2018/03/25 時点ではベータ版で、通常プランと比較していくつかの制約はありますが、無料で利用できます。早速使ってみました。今回のブログエントリではサービスを選択して利用可能にする所までの手順を紹介します。あくまでベータ版であり、今後の仕様変更等により以下の内容は正しい情報ではなくなる可能性もあります。以下の内容は 2018/03/25 時点での情報であることをご了承ください。


また、以下で紹介する IBM Cloud から提供されているブロックチェーンサービスは、IBM Cloud の無料アカウント版であるライトプランからは利用できません(2018/03/25 時点)。以下で紹介する Starter Membership Plan のベータ版は無料ですが、ライトプランのアカウントからはサービスを選択することはできません。実際に試す場合はクレジットカードを登録するなどしてスタンダードプラン等に移行してからご利用ください。


IBM Cloud にログインしてからカタログを表示し、ブロックチェーンカテゴリーを選択すると、対象サービスが "Blockchain" だけに絞り込まれます。これを選択します:
2018032401


次の画面でリージョンやプランを選択します。今回紹介する Starter Membership Plan は 2018/03/25 時点では米国南部リージョンからのみ提供されています。そのためロケーションを選択する箇所で「米国南部」を選ぶようにしてください:
2018032402


画面を下にスクロールすると利用プランの選択画面になります。上記で米国南部リージョンを選択しているとここが選択肢になっていて、Starter Membership Plan か Enterprise Membership Plan が選べるようになっているはずです(米国南部以外のリージョンだと有料の Enterprise Membership Plan のみ)。ここで Starter Membership Plan を選択して「作成」ボタンをクリックします:
2018032403


なお上図にも書かれているように Starter Membership Plan の場合、以下のような制約事項があります。シングルピア環境なので多数決をとるようなスマートコントラクトを実装することはできませんが、アプリケーションとしての実装はほぼ変わらないものを動かすことが可能になります:
・組織は2つまで
・各組織ごとに1ピアまで


サービスが作成されるとダッシュボード内のサービス一覧内にブロックチェーンサービスが表示されるようになります:
2018032404


作成したブロックチェーンサービスを選択するとブロックチェーンサービスの概要が表示されます(この辺りはプランによる違いはないと思われます)。ここから実際にブロックチェーンを操作したり管理するためのダッシュボードを開いてみます。「管理」タブの「起動」ボタンをクリックします:
2018032405


すると別ウィンドウでブロックチェーン環境のダッシュボードが表示されます。下画面ではトランザクションの順番を決定するオーダラーや、CA(認証局)、そしてピアとなるサーバー環境が動いている様子が確認できます:
2018032406


これまで自分で Hyperledger Fabric 環境を構築しようとすると、サーバー環境を用意した上でこれらの各種サーバーを自分で作って運用する必要がありました。そこまでの構築作業とサーバーとしての運用部分を IBM Cloud に任せて、実際のアプリケーション開発・実行やユーザー登録といった実務に集中できる環境として提供されていることが分かります。ブロックチェーンに興味のある方は是非今のうちに色々使ってみてはいかがでしょうか?

なお、今回は IBM Cloud 上にサービスを作る作業までを紹介しました。次回以降でこのサービスにビジネスネットワークアプリケーションをデプロイして動かせるようになるまでの手順を紹介する予定です。



タイトル通りですが、「『じゃじゃじゃじゃーん』をリズムに変換する Node-RED 用ノード」を作ってみました。


ほとんどの人はこの時点でどんな処理をするノードか理解ができてないと思うので、その補足です。このノードを作るきっかけになったのはこちらのまとめサイトでした:
【超能力者】知恵袋「何の曲か分かりますか?てんてててん てんてんてて」→「戦場のメリークリスマスですね」「なんで分かるんだ!?」


要するに「じゃじゃじゃじゃーん」という日本語テキスト(音階なし、正確なリズムもわからない)だけを頼りに「交響曲第5番、『運命』」のように曲を探し出すという(超)能力を持った人がいて、こりゃすげー!と。

なるほど、面白そうだ。最終的にはこれと同じことをシステム化できないかなあ、と考えているわけですが、その開発の途中で「とりあえずは日本語テキストからリズムを取り出す」仕組みを作り、そこから少々脱線して「その仕組を Node-RED のノードにしてみた」のが今回紹介するノード: node-red-contrib-dotnsf-jajajajan です:
https://www.npmjs.com/package/node-red-contrib-dotnsf-jajajajan

2017092300


利用するにはまず Node-RED 環境を(ローカルでも IBM Bluemix でも)用意し、そこからこのノードを導入します。ローカルであれば以下のコマンドでインストールできます:
$ npm install node-red-contrib-dotnsf-jajajajan

IBM Bluemix の Node-RED の場合はメニューからパレット管理機能を使ってインストールします:
2017101401


パレットの管理画面において「ノードを追加」タブを選び、検索文字列に "jajaja" などと入力すると見つかります(私のミスで複数バージョンが登録されてしまいました。最新バージョンのものを指定して「ノードを追加」してください):
2017101402


この状態で Node-RED を起動すると機能カテゴリ内に音符アイコンの "jajajajan" というノードが追加されて、キャンバス上で使えるようになります:
2017092301


このノードの挙動を確認するために以下のようなシンプルなフローを作ってみます。入力カテゴリの inject ノードと、出力カテゴリの debug ノード、そしてこの jajajajan ノードを配置し、以下のように配線します:
2017092302


inject ノードをダブルクリックして、Payload の種類をデフォルトの timestamp から string に変更し、その値を上記で示したような日本語のリズムテキストにします。以下の例ではまさに『運命』の有名な部分である「じゃじゃじゃじゃーん、ララララーン」としています(「じゃ」でも「ラ」でも同じように処理することができることを確認するため、わざと別の表現にしています)。ここで指定したテキストが msg.payload として jajajajan ノードに渡されて処理されます。入力し終わったら「終了」ボタン:
2017092303


これでフローの準備はできました。動作を確認するため「デプロイ」します:
2017092304


デプロイできたら、画面右ペインを "debug" タブに切り替えたことを確認してから、inject ノードの左にあるボタン部分をクリックします。クリックしたタイミングで指定したテキスト(今回の例では「じゃじゃじゃじゃーん、ララララーン」)が msg.payload として jajajajan ノードに渡されます。
2017092305


クリックすると、不定のタイミングで debug タブに文字が表示されてゆくことが確認できます。このタイミングに関してはネットワーク依存があることと、Node.js 上で動く Node-RED が非同期処理を行うことから必ずしも厳密なタイミングではないのですが、なんとなく「じゃ」「じゃ」「じゃ」「じゃーん」「ラ」「ラ」「ラ」「ラーン」のリズムで1行ずつ表示されている(はず)です:
2017092306


出力されている内容を詳しく見てみると、"8" とか "2" とか数字が表示されています。実はこれは音符の長さを表していて、"8" は「8分音符」、"2" は「半音符(2分音符)」を意味して、その長さに合わせて debug 出力も制御されています。現在の仕様では "8" では 0.5 秒後、"2" では 2 秒後に次の音符が表示されるようにしています(なので "8" の次はすぐに表示されますが、"2" の次が表示されるまでには少し時間がかかります)。結果的になんとなく「じゃ」「じゃ」「じゃ」「じゃーん」「ラ」「ラ」「ラ」「ラーン」というリズムに合わせて1行ずつ表示されているように見える・・・のではないかと思っています(苦笑):
2017092307


試しに『メヌエット』の出だし部分である「タンタタタタタンタンタン」で試すとこんな感じです。最初の「タン」が4分音符で、そこから8分音符が4回続いて・・・というリズムで解釈されていることがわかります:
2017092308


と、またこんなくっだらないノードを作ってしまった。。どうしても使ってみたいという変わった人がいたら使ってください。ちなみにソースコードはこちらです(日本語処理の部分はかなりハードコードに依存しているので、他の言語用に移植するのが難しいかも・・):
https://github.com/dotnsf/node-red-contrib-dotnsf-jajajajan


脱線した話を元に戻すと、このノードで実現している仕組みを使ってテキストをリズムに変えて、取り出したリズムの情報をあらかじめ楽譜を元にリズムだけを取り出した楽曲のデータベースから曖昧検索して近いものを探す、という方法で冒頭で紹介したような超能力者みたいな仕組みをシステム化できないか、と考えています。こちらも諦めているわけではなく、ある程度は動くようになっている(楽譜そのものと、楽譜から主旋律を探す仕組みに苦戦している)ので、人前に出せるようになったら公開するかもしれません。まあ、そうそう簡単なものではないと分かっている上に自分が音楽や楽器が得意ではないので、まだ躓いてすらいない落とし穴が待っているかもしれませんが・・・

複数の楽器向けに書かれている楽譜から主旋律(というのかな?人間がよく知ってるパート)を探す方法を知っている人がいたら教えていただけるとうれしいです。

IBM Bluemix からも提供されている IBM の DBaaS サービスである dashDB に Node.js からアクセスする方法を紹介します。実際には dashDB だけでなく、DB2 のサービスやオンプレミスデータベースへも同様に応用できますが、今回は Bluemix 上の DB2/dashDB 関連サービスを例に紹介します:
2017063002


dashDB は行指向/列指向型のテーブルをどちらも作成することができるリレーショナル・データベースのサービスですが、そのデータベースシステムとしての実体は IBM DB2 です。というわけで、このライブラリを使ってアクセスします:
https://www.npmjs.com/package/ibm_db

2017063001


まず以下のコマンドを実行して ibm_db をインストールします(このコマンドだけで DB2 ODBC Driver ごとインストールされます):
$ npm install ibm_db


そして以下のようなコードを用意して dashDB にアクセスします:

(settings.js)
exports.db_host = 'dashdb-entry-yp-XXXXXXXX.services.dal.bluemix.net';
exports.db_port = 50000;
exports.db_name = 'BLUDB';
exports.db_username = 'dashNNNN';
exports.db_password = 'PASSWORD';

(sample.js)
var ibm_db = require( 'ibm_db' );
var settings = require( './settings' );

var db_str = "DATABASE=" + settings.db_name
  + ";HOSTNAME=" + settings.db_host
  + ";UID=" + settings.db_username
  + ";PWD=" + settings.db_password
  + ";PORT=" + settings.db_port
  + ";PROTOCOL=TCPIP";
var sql = "select OBJECTID, NAME from SAMPLES.GEO_CUSTOMER limit 10";

ibm_db.open( db_str, function( err, conn ){
  if( err ) return console.log( err );

  conn.query( sql, function( err, data ){
    if( err ) console.log( err );
    else console.log( data );

    conn.close( function(){
      console.log( 'done.' );
    });
  });
});

settings.js の中身はユーザー名やパスワードといった dashDB に接続するためのサービス資格情報です。IBM Bluemix の画面から取得できる値を使って、実際の値で書き換えて使ってください:

2017063003


アプリケーションの実体は sample.js です。今回の例ではシンプルに接続して、サンプルデータとして GEO_CUSTOMER テーブルから OBJECTID と NAME の値を 10 件だけ取得する、という SQL (青字部分)を実行しました。また settings.js で定義した情報を取り出して接続文字列(赤字部分)を生成しています。

node コマンドで sample.js を実行して、以下のような結果が表示されれば成功です:
$ node sample.js
[ { OBJECTID: 1322, NAME: 'Kami Labarbera' },
  { OBJECTID: 1323, NAME: 'Johnathon Tunney' },
     :
  { OBJECTID: 1587, NAME: 'Althea Alcazar' } ]
done.







 

Node.js の処理内で unzip を実現する方法を紹介します。アップロードなどで zip ファイルを受取って、それをダイナミックに展開して特定のファイルを取り出す、といった仕組みを Node.js で実現する場合に必要な実装の例です。

この仕組みを実現するために、node-unzip という便利なライブラリがあるので、これを使うことにします:
https://www.npmjs.com/package/unzip

2017070601


fs ライブラリと併用して、こんな感じで使います(zip ファイル内の全ファイルを展開する例):
var fs = require( 'fs' );
var unzip = require( 'unzip' );

  :
  :

fs.createReadStream( './uploads/archive.zip' )
    .pipe( unzip.Extract( { path: './tmp/' } ) );

特定のファイルだけ(以下の例では拡張子が ".xml" のものだけ)を展開する場合は以下のようにします:
var fs = require( 'fs' );
var unzip = require( 'unzip' );

  :
  :

fs.createReadStream( './uploads/archive.zip' )
    .pipe( unzip.Parse() )
    .on( 'entry', function( entry ){
      var filename = entry.path;  //. ファイル名
      var type = entry.type;  //. 'Directory' または 'File'
      var size = entry.size;   //. ファイルサイズ

      if( filename.toLowerCase().endsWith( ".xml" ) ){
//. ".xml" で終わるファイル名だった場合のみ展開 entry.pipe( fs.createWriteStream( './tmp/' + filename ) ); }else{ entry.autodrain(); } });

そもそもの元ファイルが zip 圧縮されていたり、大量のファイルデータをアップロードして登録したい場合などは、目的のファイルを zip して、1回でまとめてアップロードできると便利なのですが、この方法であれば受け取った zip を展開して・・・という処理が実現できます。


最近、ボット関連の API や SDK をよく見るわりに、自分では使う機会が少なかったので、今更ながら1つ作ってみました。

今回作ってみたのは「シェルボット」です。名前の通り、ボットでシェルっぽいインターフェースを実現しました。何言ってるかよくわからない人はこちらの画面を参照ください:
2017060901



ボットっぽい対話型インターフェースを使って、対話しているかのようにシェルコマンドを実行します。今回はインターフェースに独自の HTML ページを用意しましたが、ぶっちゃけ LINE などでも(Messaging API を使うなどすれば)応用できると思っています。

#「チャットボット」とは違うけど「ボット」ですっ!


ソースコードを github で公開しておきました。セキュリティ的な面はまだまだ改良の余地があると思っています(rm コマンド他は実行不可にしていますが、本当は他にも実行を制御するコマンドを考慮したほうがいいと思う):
https://github.com/dotnsf/shellbot


↑このソースコードはビジュアルフローエディタである Node-RED で使う前提のものです。(IBM Bluemix などを使って)Node-RED 環境を用意し、func-exec ノードを追加した上でキャンバスに shellbot_nodes.txt の内容をインポートして、ブラウザで /shell にアクセスするだけです(詳しくは README.md 参照)。

#あー、あと今のところ Linux/Unix 系 OS に導入する前提です。


実際に Node-RED 環境上にインポートした様子のスクリーンショットがこちらです。2本のシンプルな HTTP リクエスト処理が定義されているだけのもの(うち1つは HTML 画面定義)ですが、本当にこれだけでこのシェルボットが動きます:
2017060902


実は今まで「ボット」=「チャットボット」=「コンシェルジュ」的なイメージを持っていてハードルが高かったのですが、今回のアプリを作った結果、難しく考えずに「既存アプリケーションのインターフェースを対話型にする」という実装もアリかな、と思うようになりました。


このページのトップヘ