2020年10月11日日曜日

サービス実行後に実行するプログラムを登録する

今回のテーマは、タイトルは違いますが前回のエントリと同じです。

前回のエントリでは、REST API の戻り値が複数ある場合に HCL Domino Volt のページ上にある表へセットする方法について紹介しました。REST API が戻した JSON の値を Volt のフォーム上の表へセットするために、フォームのイベントへ「サービス構成」を行うものです。

前回のおさらいをすると、REST API が返す JSON は次に示すような構造でした。

{
  "results": [
    {
      "formatted_address": "値(住所)",
    },
    ・・・
  ]
}

この JSON から "results" という配列にあるオブジェクトから "formatted_address" というキーの値を取り出しました。"results" は配列なので、複数のオブジェクトが存在する場合があります。

今回扱う JSON は次に示すとおり、配列の中にあるオブジェクトの中にさらに配列がある「入れ子」構造です。

{
   "Feature": [
      {
         "Property": {
            "WeatherList": {
               "Weather": [
                  {
                     "Type": "observation",
                     "Date": "202009212320",
                     "Rainfall": 0
                  },
                  ・・・
               ]
            }
         }
      }
   ]
}


ただし今回扱いたかった JSONでは、上位の配列 "Feature" にはオブジェクトが1つだけ存在し、そのオブジェクトの中の配列 "Weather" は複数のオブジェクトを持つ、という約束があるようでした。
下位の配列のオブジェクトにある Type, Date, Rainfall の値を Volt の表で表示したいのです。


REST API が返す JSON に配列の入れ子(配列の中に配列)が存在し、かつ最下層の配列から値を取得したい場合、現状の Volt では表の中に表を作るなどして、入れ子の階層をレスポンスの配列階層と合わせなければ「サービス構成」による構成中に「割り当てが無効です。ソースとターゲットは祖先と同じ数のリスト(または表)を持つ必要があります。」(下図赤枠)と表示され、構成できません。


そこで試してみたところ、表の中に表を作ることは可能でしたので、なんとなく入れ子の表を作ってみました。

下位の表には列として3つの単一行エントリを配置しています。


するとサービス構成で割り当てすることができました。 ただし、構成した後にプレビューしてみると、入れ子構造の表を表示することができません。


現状では JSON で入れ子の配列の値を取得できても、それを Volt の表で表現することができないようでした。


このことをサポートへ報告したところ「入れ子にされた表の表示を現状サポートしていない」(※2020年9月の話です)とのこと。

食い下がってなんとか表示する方法について聞いてみたところ、奥の手のような回避策をご提案いただきました。

今回はその回避策をご紹介します。


実は、「サービス構成」で入れ子の表(にあるフィールド)へ割り当てた場合、表示はできませんでしたが、値は割り当てたとおりにセットされていたのです。


この回避策は「サービス構成」によって入れ子の表に値がセットされていることを前提としていますが、「サービス構成」で作成したサービスが終了したタイミングで、次のようなプログラムを実行する、というものでした。

  1. 「サービス構成」で取得できた値を表から取り出しながら
  2. <table>...</table>等のHTMLタグを付加して加工した文字列を作成
  3. 作成した文字列をHTMLフィールドへセット


まずは「サービス構成」で定義した処理の終了後に実行するプログラムです。

var srv = form.getServiceConfiguration( "SC_ServiceConfig0" );
srv.connectEvent( "onCallFinished", function( success ) {
  if ( success ) {
    var s = app.getSharedData().printTable( BO.F_Table1 );
    form.getPage( "P_NewPage1" ).F_HTMLArea1.setContent( s );
  }
});

ここで "SC_ServiceConfig0" は、onShow イベントで「サービス構成」を設定する際に「4.詳細」タブに指定したIDです。ここではIDにデフォルト値として設定されていたものを使っています


このサービスに onCallFinished というイベントを設定しています。onCallFinished を設定することで、サービス構成で設定した処理の終了時に任意の処理を実行することが可能になります。

サービス構成で設定した処理が正常に終了した場合(if (success) の部分)に実行するプログラムとして、printTable を指定しています。printTable の頭についている "app.getSharedData()." ですが、これはフォーム上にある「カスタムJavaScript」を定義したり呼び出す場合に使います。ここで呼び出しているプログラムが次に示すプログラム printTable です。このプログラムを記述するために app.getSharedData() を使っています。

プログラムの引数 "BO.F_Table1" ですが、F_Table1 は入れ子の表の上位階層にある表のIDで、その頭についている BO は Business Object の略のようです。

プログラム printTable を実行すると HTML の文字列を返します。

その HTML 文字列をページ( "P_NewPage1" )にある HTML エリア( "F_HTMLArea1" )へセットします。※HTML エリアとはパレットの「特殊」にある 「HTML」を指します(下図)


以上のプログラムと次に示すプログラムを、フォームの onLoad イベントに記述しています。


以下は、表から値を取り出しながら HTML を生成するプログラムです。入れ子の表に対応するため再帰的に呼び出し可能な関数になっています。

app.getSharedData().printTable = function( table ) {
  var s = "<table width='90%' cellpadding='0' cellspacing='0'>";
  for(var i = 0; i < table.getLength(); i++) {
    var row = table.get( i );
    s += "<tr>";
    var ol = row.getChildren();
    for( var j = 0; j < ol.getLength(); j++ ) {
      var f = ol.get(j);
      if( f.getType() === "BusinessObjectList" ) {
        var innerS = app.getSharedData().printTable( f );
        s += innerS;
      } else {
        s += "<td>";
        var v = f.getValue();
        s += v;
      }
      s += "</td>";
    }
    s += "</tr>";
  }
  s += "</table>";
  return s;
}

以上のような奥の手を使うことで実現した結果が下図にある7行3列の(Volt アプリなのに Volt アプリっぽくない)表です。


今回のように REST API が返す値を加工して表示したい場合に使えそうです。

ノーコード/ローコードのツールでここまでやるのもどうかと思いますが、JavaScriptで作りこみたい場合にこちらのドキュメントが参考になると思います。

2020年9月22日火曜日

REST API で取得した値を Volt の表へセットする

先日のノーツコンソーシアムのアプリ開発研究会で取り組んだ、Web API で取得したjson 配列の値を Volt のフォームに追加した表へセットする方法についてご紹介します。

使用する Web API は Google のジオコーディング API です。この API を使うには API キーが必要なのですが、キーを入手する方法についてはこのあたりのページが参考になるかと思います。

APIキーを入手できたら、次のURLへGET要求します。

https://maps.googleapis.com/maps/api/geocode/json?language=ja&latlng=<緯度>,<経度>&key=<APIキー>

※出力フォーマットとして json を指定します
※表示する住所を日本語にしたいので language=ja を追加しています

仮に、取得した位置情報が自由が丘駅ホーム、入手したAPIキーが "abcd1234" とすると、URLは次のようになります。

https://maps.googleapis.com/maps/api/geocode/json?latlng=35.60869829275,139.66870970056&key=abcd1234

まっとうなAPIキーをセットしたURLの場合、ブラウザのアドレス欄へ指定すると、REST API のレスポンスが表示されます(下図)。

この json から住所を取得したいのですが、位置情報から取得できる住所が複数の場合があります。上の図では縦スクロールバーのサイズから察するとおり複数の住所が取得できました。

このような複数の値が戻ってくることが分かっている値を Volt のフォーム上に表示したい場合、表を使用すると便利です。戻り値の数に応じて行数が自動で変化しますので、戻り値の数が10あれば、表に10行の住所を表示してくれます。

さて今回 json から取得する値は、results という配列にある formatted_address の値とします。

formatted_address をVolt の表の列に割り当てていきます。

今回も HCL社が用意している Application Sandbox を利用してアプリケーションを作成していきます。こちらはライセンスを持っていない方でもアカウント登録さえ行えば利用できますので、Domino Volt での開発を試してみたい方にお勧めします。

開発の流れは次のとおりです。
  1. 新規アプリケーションの作成
  2. 表を追加
  3. 列を追加
  4. イベントとサービス構成を追加
では始めます。

Sandbox にログイン後 Volt の初期画面から「新規アプリケーションの作成」をクリックします。「白紙から」を選択して[次へ]ボタンをクリックします。アプリケーション名を「住所リスト」として[作成]ボタンをクリックします。

ページに表を追加します。画面左側のパレットから「特殊」にある「表」をクリックします(ダブルクリックすると複数の表が追加されますのでシングルクリックしましょう)。するとページ内に表が追加されると思います。表をページ内の任意の場所へ追加したい場合は、「特殊」にある「表」をドラッグして、ページ内の任意の場所へドロップするほうが便利かもしれません。

この表へ列を追加します。今回は住所だけを表示したいので1列だけ追加します。画面右側の「アウトライン」から「ページ1」の左にある > をクリックすると下に表示される「表」をクリックします。画面左側のパレットから「フィールド」にある「単一行エントリー」をクリックします。すると表に単一行エントリーが追加されると思います。表内に追加された単一行エントリーで太字で「単一行エントリー」と表示されている文字をクリックすると文字を編集できますので、これを「住所」と書き換えます。この「住所」が列のタイトルとして表示されます。

列を追加したら、ここで列幅を(デフォルトは「10文字」と狭いので)調整します。列幅は表のプロパティーから編集できます。画面右側の「アウトライン」から「ページ1」をクリックします。そして画面中央の表の右上に表示される歯車アイコン(カーソルを持っていくと「表プロパティーの編集」と表示されます)をクリックします。

「「表」プロパティの編集」ダイアログが表示されたら、その上部にあるメニューから「拡張」をクリックして、「オプション:」にある住所列の「幅(概略値)」の値を 500 までの適当な数値に書き換えます。書き換えたら[OK]ボタンをクリックしてダイアログを閉じます。

次にフォームへイベントを追加します。画面上部のメニューから「イベント」をクリックして、画面左側の「フォーム・イベント」欄の下にある[追加]というリンクをクリックします。

するとイベントのリストが表示されます。ここから onShow をクリックします。

すると onShow イベントの編集画面が表示されます。「事前定義アクション」にある「サービスの呼び出し」にチェックを付けます。すると「サービス構成の追加/編集」というリンクが現れるので、これをクリックします。

「サービス構成」というダイアログが表示されますので、ここから「API のレスポンス」と「フォーム上のフィールド」の割り当てを設定します。まずは「URLを入力」を選択します。自由が丘の位置情報とAPIキーを含むURLをURL欄へ入力します。ここでURL欄の右側にある歯車アイコンをクリックします。

「サービスの詳細」ダイアログが表示されます。ここではフォーム上のフィールドから取得可能な値をURLの各パラメータへセットしたい場合に、フィールドと紐づけさせたいURLパラメータを指定することができます。今回はURLにある3つのパラメータ「言語(language)、緯度経度(latlng)、,APIキー(key)」はどのフィールドとも紐づけしません。そのため、この画面にある「割り当て可能」についた3つの青いチェックボックスをクリックしてチェックを外した状態にして、[OK]ボタンをクリックします。※下図はチェックを外す前の状態です

「サービス構成」画面に戻ったら、その画面上部にある「3.出力」をクリックします。ここで「2.入力」をスルーするのは、フォーム上のフィールドとURLパラメータを紐づけしないからです。「3.出力」では戻ってきた json の項目("ソース"と呼びます)を、フォーム上のフィールド("ターゲット"と呼びます)へ割り当てます。画面左側の「ソースの選択」から "results" の左にある > をクリックして展開し、"formatted_address" をクリックします。するとクリックした文字が太字に変化します。続いて画面右側の「ターゲットの選択」から”表”の左にある > をクリックして展開し、"住所"をクリックします。こちらもクリックした文字が太字に変わります。"formatted_address" と "住所" の両方が太字になっている状態で、その中間にある[出力の割り当て]ボタンをクリックします。

すると画面下部の「割り当てられている出力」欄へ追加されます(下図)。[OK]ボタンをクリックして「サービス構成」ダイアログを閉じます。




以上で(見た目はさておき...)機能としては完成です。

画面右上にある[保存]ボタンをクリックして、その左にある[プレビュー]をクリックします。すると下図のような感じで表示されると思います。

この表には5行しか表示されておらず、縦のスクロールバーも表示されていませんが、実は戻り値は12個存在しました。表の上でスクロールの操作を行うことで、表示されていない残りの行も見ることができました。

今回は API の実行タイミングを「フォームを表示したとき」としたかったので「フォームのイベント」にサービスを構成しましたが、例えば、フォーム上にボタンを設置して、ボタンをクリックしたタイミングで API を実行したい場合は、今回と同様のサービス構成をボタンの onClick イベントへ追加することになります。

また今回構成したサービスでは「2.入力」をスルーしましたが、フォーム上に緯度経度のフィールドを用意することで、それらの値をURLパラメータに代入するといったサービスにしたい場合は「2.入力」の画面で設定することになります。

【配列の入れ子に注意しましょう】
REST API の戻り値にある配列の値を表へセットする場合、配列の構造に注意が必要です。今回の REST API では対象となりませんでしたが、「配列の中に配列がある」といった構造の場合は「フォームの中に追加した表の内側にさらに表を追加する」といったように、ソースの入れ子構造にあわせてターゲット側も入れ子構造にしなければサービスを構成することができません。しかしながら現状の Volt は入れ子の表を作ることはできるものの表をそれっぽく表示することができません。そのため取得した値を表示することができないのです。この問題をサポートへ報告したところ回避する手段を教えてもらうことができましたので、機会があれば紹介したいと思います。

2020年9月11日金曜日

パブリックアクセス権限とパブリック文書

昨晩は仕事終わりに「のの会」に参加しました。 

以前の「のの会」で、読者フィールドと作成者フィールドについてお話ししたところ、パブリック文書についてのリクエストがありました。

パブリック文書は、アクセス制御リストの画面(下図)に表示されるワードです。


今回はご要望にお応えして標記のテーマでお話しました。

内容は次のスライドにまとめています。


スライドには、実装方法とメールデータベースでの設定に加え、読者フィールド/作成者フィールドと共存した場合の挙動の検証結果をクイズ形式で記載しています。
※検証にはバージョン11.0.1FP1のNotes/Dominoを使用しています

クイズの全問正解者は(検証中の私を含め)今回の「のの会」会場には現れませんでした。

パブリックアクセス権限とパブリック文書について、みなさんは正しく理解されていることと思いますが、もしご興味がありましたらクイズにもチャレンジしてみてください。

2020年8月22日土曜日

資料をアップしました「初めての HCL Sametime」

2020年8月度の「のの会」の翌日から夏季休暇をいただいたこともあってすっかり失念しておりましたが、お話しましたことを SlideShare へアップしました。 資料公開までの間に Sametime 11.0 FP2 のリリースがありましたので、資料を少し加筆修正しました。 これから Sametime に触れる方の参考になれば幸いです。

2020年8月20日木曜日

JSON から目的の値を取り出す(2)

 以前のエントリで JSON にある配列の最初の要素から特定の項目の値を取得するコードを書きました。

今回は、配列にあるすべての要素から特定の項目の値を書き出すコードをご紹介したいと思います。


JSON 今回扱うJSON文字列ですが、 results という配列に1つ以上(以下の例では3つ)の要素があり、それぞれの要素に address1 から address3 までの項目があるものとします。


{
 "results": [
  {
   "address1":"a-1",
   "address2":"a-2",
   "address3":"a-3"
  },
  {
   "address1":"b-1",
   "address2":"b-2",
   "address3":"b-3"
  },
  {
   "address1":"c-1",
   "address2":"c-2",
   "address3":"c-3"
  }
 ]
}


ここから address1 から address3 の値を取得するコードは以下のようになります。


Dim JSON As String
Dim nav As NotesJSONNavigator
Dim elm As NotesJSONElement
Dim arr As NotesJSONArray
Dim i As Long

JSON = |{"results": [{"address1":"a-1","address2":"a-2","address3":"a-3"},{"address1":"b-1","address2":"b-2","address3":"b-3"},{"address1":"c-1","address2":"c-2","address3":"c-3"}]}|

Set nav = ss.CreateJSONNavigator(JSON)
Set elm = nav.Getelementbypointer("/results")
Set arr = elm.Value
	
For i = 0 To arr.Size - 1
	Print nav.Getelementbypointer( "/results/" & CStr( i ) & "/address1" ).Value
	Print nav.Getelementbypointer( "/results/" & CStr( i ) & "/address2" ).Value
	Print nav.Getelementbypointer( "/results/" & CStr( i ) & "/address3" ).Value
Next


コードの10行目では、GetElementByPointer メソッドを使い、JSON から要素 results を取得して NotesJSONElement クラスのインスタンス elm を作ります。

ちなみに、ここでは要素 results のタイプが配列であることがあらかじめわかっているので、elm の値を NotesJSONArray クラスのインスタンス arr へセットしていますが、タイプがわかっていない場合は NotesJSONElement クラスの Type プロパティで調べることができます。

下表は type プロパティの値を比較する際に使用できる定数の名前とその値です。
タイプ値(Integer)
Jsonelem_type_object1
Jsonelem_type_array2
Jsonelem_type_string3
Jsonelem_type_number4
Jsonelem_type_boolean5
Jsonelem_type_empty64

話を元にもどします。

JSON の配列の要素の数を知りたいとき、NotesJSONArray クラスのプロパティ Size を呼び出します。配列要素の数が1つなら、Size の戻り値は1となります。

14行目から16行目で "/Results/[配列要素の番号]/AddressX" のようにして、それぞれの要素から値を取り出します。配列要素の番号は、最初の要素が0番から始まるため、13行目では値の範囲を 0 から<Size の戻り値から1を引いた値>までとしています。


2020年7月15日水曜日

GPSセンサーの無いPCでも位置情報を取得できました

HCL Nomad では、端末の GPS 機能を利用して位置情報を取得するための LotusScript のクラスがあります。 

イマドキは GPS センサーが無い PC でもブラウザさえあれば Wi-Fi から位置情報を取得することができるらしいと噂で聞いたことがあります。

ところで先日、ノーツコンソーシアムのアプリ開発研究会に参加して Domino Volt を使ったアプリ開発を行いました。先月は Domino Volt を使ったアプリ開発のハンズオンだったのですが、今月は各自テーマを決めて自習する形式でした。※最近は全員がリモート参加のためグループでの取り組みが困難なのです

私は、Domino Volt ではまだ経験の無い Web API を利用したものにチャレンジしたかったのと、冒頭の「位置情報をGPSセンサー無しに取得する」を組み合わせて、位置情報を住所に変換する「リバースジオコーディング」アプリに取り組みました。

今回初めて Volt アプリを何もないところから作成したこともあり、研究会の限られた時間の中では Web API の部分しか実現できなかったのですが、その後 Domino Volt の Interface object についての Document の中に app.getLocation というコールバックファンクションがあることに気付き、今朝から取り組みました。

コールバックファンクションというのは、情報の取得が終わった後に呼び出される機能といったところでしょうか。

そして app.getLocation を使って取得できた位置情報から緯度と経度を取り出し、フォーム上の入力欄(単一行エントリー)へセットすることができました。

自宅PCでブラウザからこの Volt アプリへアクセスしてみたところ、取得できた緯度経度はGPSの値と大きな違いはなさそうでした。

次の画面ショットは、自由が丘駅のホームで iPhone からこの Volt アプリへアクセスしたものです。住所の精度は未確認ですが「自由が丘」というワードがあるので位置情報が大きくずれていることはなさそうです。
フォームを表示したとき、緯度と経度のデフォルト値をセット

実行ボタンをタップするとWeb APIを呼び出し、レスポンスを表へセット

これを実現するため、次のコードをフォーム「F_Form1」を表示するときに実行される onShow イベントへ設定しています。
var myForm = app.getForm('F_Form1');
var formBO = myForm.getBO();
var highAccuracy = true;
var myCallbackFunction = function (position) {
  if (position !== null) {
    formBO.F_SingleLine4.setValue(position.coords.latitude);
    formBO.F_SingleLine5.setValue(position.coords.longitude);
  }
};
app.getLocation(myCallbackFunction,highAccuracy);
フォームのイベントへカスタムアクションとしてJavaScriptのコードを追加


6行目の「F_SingleLine4」は緯度、7行目の「F_SingleLine5」は経度の入力欄です。フォームを表示すると、現在地の緯度と経度がデフォルト値としてセットされるという仕組みができました。

なお、このアプリをノーツコンソーシアムで用意していただいた Domino Volt 環境で実行すると、きちんと位置情報を取得できるのですが、私個人のPC内にある仮想環境上に構築した Domino Volt 環境では取得することができませんでした。検証できていませんが私の環境は https に対応していないことから、ひょっとすると位置情報を取得するためには https でアクセスできなければならないといったセキュリティ要件があるのかもしれません。

2020年7月2日木曜日

Sametime 関連 nsf ファイル

Sametime のインストールを経験して3ヶ月が経過した頃、管理クライアントを操作していてある事に気づきました。

「タイトルがやたら長いデータベースがある...」

それは Sametime のインストールによって追加された vpuserinfo.nsf というファイルなのですが、そのタイトルがこちらです。

Extended access controls are enabled on this database. You must modify the database on a version 6 or later Domino server.

私は検証環境として Sametime サーバーを2台構築しているのですが、他方のサーバーも同じファイル名になっていました。

ここで Sametime インストールで追加されたファイルのタイトルを見てみると「エラーメッセージか?」と感じるような明らかに変なタイトルが幾つもあることがわかりました。※下図赤枠部分のファイルです
タイトルが明らかに不正なnsfファイル

ファイル名不正なタイトル
 vpuserinfo.nsf Extended access controls are enabled on this database. You must modify the database on a version 6 or later Domino server.
 stauths.nsf You cannot do a remote queue put to a pre-R5 server
 stautht.nsf You cannot administer Enterprise Directories on a pre-R5 server
stconf.nsf  Network protocol error: message from server is too large
 stconfig.nsf Accelerated replica creation cannot be used with an encrypted database
 stcs.nsf Invalid profile 
 stdomino.nsf Cannot close a database within an NSFSearchStart - NSFSearchStop loop that was opened outside of the loop
 stlog.nsf LookupExtended on server %a
 stnamechange.nsf Invalid VJournal property found


こういった事象は Sametime のフォーラム技術情報にも似たような報告がありました。



ところが、これらが私の環境と違う点は、CentOS8 でなく CentOS7 である事と、11.0 から 11.0FP1へのアップグレードではなく 11.0FP1 を新規にインストールしている事です。

そこでサポートへ問い合わせてみたところ、次の事がわかりました。

  • Linux 版 Sametime のインストールで Sametime 用のデータベースを作成する際データベースタイトル設定時にインストーラー側の問題で不正な文字列が入りタイトルにエラーメッセージのような文字列が入り不正になる
  • 技術情報では Sametime 11.0 から 11.0FP1 へのアップグレード時と記載があるがバージョンアップに限定されず、Sametime 11 や Sametime 11.0 FP1 の Linux 版 Sametime サーバー新規インストールの場合にも発生することを確認している
  • Windows 版では発生しない
  • ファイル名が正しいならば Sametime の機能上の問題はない
  • 正しいタイトルをテンプレートが保持しているため、テンプレートがあるファイルについては不正なタイトルは Design タスクが稼働すれば正しい名前に置換される。ただ、データベースの設計の引継ぎが無効にされている vpuserinfo.nsf は管理者が手動で「Sametime User Information」と変更しないと変わらない
つまりは、Design タスクを実行すればほぼ解決、という事なのですが、今回は検証環境という事で、普段は検証後にOSをシャットダウンしてしまうことから夜間に Design タスクが動いていなかったのです。

おそらく本番環境では定期的に Design タスクを実行しているでしょうから、なかなか気付く事は無いかもしれません。


ところで Sametime インストール時に追加されるファイルにはどのようなものがあるのでしょうか。こちらもサポートに聞いてみました。

 ファイル名  概要
 stofflinemessage.nsf オフラインメッセージ(チャット相手がオフラインの時に相手に送ったメッセージ)を格納するデータベース
 stlog.nsf Sametime のログデータベース
 stconfig.nsf Sametime の設定情報を格納するデータベース
 stauths.nsf Sametime SecretKeys を格納するデータベース
 stautht.nsf Sametime のサーバーのホスト名やポート番号を格納しているデータベース
 stdomino.nsf どのユーザーがオンラインであるかを格納する為のデータベース
 stnamechange.nsf Sametime で STNameChange タスクを使用し名前変更機能を使用する際使われるデータベース
 vpuserinfo.nsf ユーザーのコンタクトリストを格納するデータベース
 stcenter.nsf Sametime 8.5.2 まで提供されていた機能のひとつで、Sametime に Web ブラウザからアクセスする場合のホームページ(起点のページ)を表示していたデータベース
 stsrc.nsf Sametime 8.5.2 まで提供されていた Sametime Classic Meeting 機能を利用するための Notes データベース。Sametime 9.0 以降では Classic Meeting 機能が提供されていないので、アクセスが製品側で意図的に禁止されています。
 stconf.nsf Sametime 8.5.2 まで提供されていた機能のひとつで、Sametime Classic Meeting 機能を利用するための Notes データベース
 stcs.nsf Sametime 8.5.2 まで提供されていた機能のひとつで、Sametime Classic Meeting 機能を利用するための Notes データベース
これらのうち次のデータベースは Sametime 8.5.2 までのリリースで使用されていたデータベースで Sametime 9.x 以降、製品としてアクセスが禁止されているとの事。
stcenter.nsf
stsrc.nsf
stconf.nsf
stcs.nsf

上の4つのデータベースは、そのまま運用するか、OS レベルでリネームし NSF ファイルとして認識されない状態にして運用してほしいとの事でした。

また、stcenter.nsf と stsrc.nsf は、Sametime Community Server のインストールでは除外するよう機能改善要望が提出されているそうです。

2020年6月20日土曜日

HCL Nomad 向け「GPS Tools」データベースについて

HCl Nomad は、緯度経度などの位置情報をスマートフォンの GPS センサーから取りこむことができます。

これまで、このブログでも GPS に関連するエントリをいくつか投稿してきました。

昨日(2020年6月19日)の「テクてくLotus技術者夜会」では、HCL Nomad で GPS から位置情報を取得する方法や、Notesデータベースに保存されている位置情報をどのように活用できるかといった観点でお話させていただきました。

夜会の資料(後日リンクを貼ります)にはコードのサンプルを記載しているのですが、資料の文字は小さすぎて見づらいし、GPSは机上で動かしても全く面白みがないということもあり、夜会の資料で紹介している全てのサンプルコードを1つの nsf ファイルにまとめて公開することにしました。

こちらから NSFTools.nsf をダウンロードできます。

GPS Tools

上のリンクから NSFTools.nsf をダウンロードしましたら、HCL Nomad でアクセスできる Domino サーバーのデータディレクトリへ配置して、都合の良いアカウントで署名してください。
HCL Nomad から Domino に配置した NSFTools.nsf へアクセスして開くことができたら、画面左上のバーガーアイコンから「オフラインで利用できるようにする」を選び、ローカルに複製(レプリカ)を作ることをお勧めします。端末側へ複製した NSF Tools を使用することで、端末側で WiFi や 4G などの電波が届かないオフラインの(Domino サーバーへアクセスできない)状態でも、取得した位置情報を安定的にデータベースへ保存することができます。

このサンプルデータベースには、「2地点間の距離を求める」といったような HCL Nomad が無くても(Notesクライアントでも)試せる機能もあるのでデータのサンプルを入れておけばよかったと少し後悔していますが、ぜひご自身の HCL Nomad を屋外へ持ち出して位置情報を収集してみてください。

2020年5月10日日曜日

Notes で QR コードを表示しよう

今回は LotusScript の NotesHTTPRequest クラスを使って Node.js のアプリと連携する Notes アプリを作ってみましたので、ご紹介します。
※ NotesHTTPRequest クラスは 10.0 の新機能です。

作ったアプリは「テキストを QR コードに変換する」ものです。

(念のため)QRコードとは次のようなものです。


過去のノーツコンソーシアムのイベントでは "notes://" で始まる Notes URL が埋め込まれた QR コードを iPad のカメラで撮影し HCL Nomad ( iOS や Android における Notes クライアントとも言える公式アプリ)で Notes アプリを開くといったデモがありましたね。

iOS 端末には QR コードを読み込む機能がありますが、HCL Nomad からその機能を呼び出して撮影したQRコードに埋め込まれたテキストをフィールドへセットしたり QR コードを生成して表示する機能は、残念ながらまだ Notes 標準の機能にはありません。現状では Notes 以外のものに頼るしかありません。

「ノーツ qr」などとググってみれば、Java や XPages で作ったアプリの例がいくつかヒットします。

けれども現状の Nomad は Java は動かないのです…
XPages ならばブラウザがあれば使えますが... 今後は Domino Volt で!という声も聞こえてきそうですが...

今回は、Notes または Nomad からアクセスできる Web サービスに頼ることにします。

では、Nomad (上の LotusScript )から送信されたテキストから QR コードを生成し、QR コードの画像を返す Web サービスを用意します。

まずは Web サービスを node.js 上に構築します。

私は Windows 10 Pro に node.js をインストールしていますので、コマンドプロンプトから次のコマンドで準備しました。
> mkdir qrapp
> cd qrapp
> npm init
> npm install express
> npm install body-parser
> npm install qrcode

上のコマンドでは、適当な場所(デスクトップなど)に qrapp というディレクトリを作成し、そのディレクトリへ npm init で package.json を作ったら、express, body-parser, qrcode をインストールしています。

QRコードの生成には node-qrcode を利用しています。漢字にも対応しているところが素晴らしい!
https://github.com/soldair/node-qrcode


qrapp ディレクトリに app.js という名前でファイルを作成します。テキストエディタ等で次のコード(たったの14行!)をコピペして保存します。これが Web サービスのメインとなるものです。
const express = require( 'express' );
const bodyParser = require( 'body-parser');
const app = express();
const port = 3000;
const QRCode = require( 'qrcode' );
app.use( bodyParser.urlencoded( { extended: true } ) );
app.use( bodyParser.json() );
app.post( '/qr',( req, res ) => {
    console.log( req.body.qr_text );
    QRCode.toDataURL( req.body.qr_text, function ( err, qrcode ) {
        res.send( qrcode );
    });
});
app.listen( port, () => console.log( 'QR-Code app listening on port 3000.' ) );

この Web サービスは、 http://<host>:3000/qr でユーザーからのリクエストを待ちます。

次の JSON 文字列を http://<host>:3000/qr へ POST すると、QR コード画像をbase64エンコードした値を含む文字列「data:image/png;base64,<base64エンコードされた画像>」を返します。

{
    "qr_text" : "Notes/Dominoと焚き火をこよなく愛する中野です。どうぞよろしくお願いします!"
}

この Web サービスが返す文字列を後述する html へ埋め込むと QRコードが現れるという仕掛けです。


Web サービスを起動するには、コマンドプロンプトから qrapp ディレクトリへ移動して、次のコマンドを投入します。
> node app.js

Ctrl + C(Ctrl キーを押しながら C をタイプ)するとWeb サービスは終了します。



次に Notes アプリを作ります。


データベース内に2つのフォームを作ります。
  • テキストを入力する "Main" フォーム
  • QR コードを表示する "qrcode" フォーム
"Main" フォームには、一つの入力可能なフィールド "qr_text" と、ホットスポットボタンがあります。

以下(Sub Click と Function getQrCode)はホットスポットボタン「QRコード表示」のコードです。
Sub Click(Source As Button)
 Dim ws As New NotesUIWorkspace
 Dim ss As New NotesSession
 Dim req As NotesHTTPRequest
 Dim doc As NotesDocument
 Dim qr_text As String
 Const url = "http://<host>:3000/qr"

 qr_text = ws.CurrentDocument.FieldGetText( "qr_text" )

 Set req = ss.CreateHTTPRequest
 Call req.SetHeaderField( "Content-Type", "application/json; charset=utf-8" )
 req.PreferStrings = True

 Set doc = New NotesDocument( ws.CurrentDocument.Document.ParentDatabase )
 doc.Form = "qrcode"
 doc.qrcode = req.Post( url, |{ "qr_text": "| & qr_text & |"}| )

 Call ws.EditDocument( False, doc, True )
End Sub

7行目の "Const url ="には、Web サービスの URL である http://<host>:3000/qr を指定します。<host>の部分は IPアドレスやホスト名に書き換えます。


もうひとつのフォーム "qrcode" には、ひとつの計算結果テキスト(次の下線部)と、その前後に html タグを書きます。
</form><img src="<計算結果の値>"><form>
</form>から<form>までの文字全体をパススルーHTMLとしています。

計算結果テキストには qrcode フィールドの値を代入しています。なおここではフォーム上に qrcode フィールドを作る必要はありません



以上で完成です。

このサンプルデータベースでは、フォーム”Main”を表示するフレームセットを作りました。データベースのプロパティから、データベースを開いた時に表示するフレームセットとして指定しています。

Web サービスを起動したら、"Main" フォームを開いてテストしてみましょう。
iPad の Nomad でテストする場合、Node.js のアプリが使用するポート 3000 へアクセスできることを確認しましょう。

QR Code アプリをタップすると…

フォーム “Main” が開きます。QR コードにしたい言葉をタイプして「QRコード表示」ボタンをタップすると…

フォーム ”qrcode” 上に QR コードを表示します!




商品コードや URL などの Notes デーベースにある様々な文字列を QR コード化する事ができそうです。

2020年5月4日月曜日

Sameime 11 インストール

私は Notes/Domino のインストール経験はありますが、OSは Windows ばかりで、Linux へは誰の手も借りずにインストールしたことがありませんでした。


そんな私が Linux で稼働する Domino へ Sametime Community Server をインストールする機会がありました。

また Sametime Meetings Preview がもうすぐ始まりそうです。=>登録ページ


Sametime のインストールについて、前バージョンの経験者からは「非常に面倒」と聞いていました。V11 では、インストーラのサイズが小さくかつ簡単になった、といったようなことが公式ブログの記事(下のURL)にも書かれています。

『HCL Sametime 11 Chat 導入ガイドを公開しました』
https://hcljapan.co.jp/software/blog/hcl-sametime-11-chat-%E5%B0%8E%E5%85%A5%E3%82%AC%E3%82%A4%E3%83%89%E3%82%92%E5%85%AC%E9%96%8B%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F



私はそんな記事を鵜吞みにしていたこともあり、完全に舐めてました。

Linux の操作も Sametime のインストールも経験の無い私が、インストールガイド(以降「ガイド」と呼びます)を読みつつ、わからないことをちまちまと調べたりサポートに問い合わせしたりした結果、Domino が既に導入済みの環境にもかからわず、完了までに約 2 人日もかかってしまったのです...



このエントリーでは、その顛末を記載します。ここでは、インストールの方法ではなく主に「はまったポイント」を取り上げます。ガイドの補足としてお読みください。



まずは Sametime V11 について知りたい方には、次の資料をご覧になることをおすすめします。

『製品情報: HCL Sametime V11 の製品紹介資料』
https://support.hcltechsw.com/csm?id=kb_article&sysparm_article=KB0078419



公開されているガイドは2種類あります。

ひとつが Windows と Linux の両方に触れている英語のものです。

『HCL Sametime 11 Installation and Administration Guide』
https://support.hcltechsw.com/csm?id=kb_article&sysparm_article=KB0074599



もうひとつは、Windows版のみ解説されている日本語のもの、

『HCL Sametime 11 Chat のインストール手順』
https://support.hcltechsw.com/csm?id=kb_article&sysparm_article=KB0074706



今回私は不慣れな Linux (CentOS7) 上へ Domino 11.0.1 、 Sametime 11.0 FP1 Community Server、Sametime 11.0 FP1 Proxy Server をインストールしてみようと思い立ち、前者のガイドを使用しています。




ガイドを読み進めてみたのですが、私にはわからないことがありました。

Standard と Limited Use の違い、Mux server、GSKit、Proxy Server、などなど...

これらは環境構築の前提として選択することが必要ですが、何を選択すればいいのかわからないので困りました。


現時点では、こういった用語について説明された V11 の文書が分散しているようで、V10 のようにまとまったヘルプがまだ存在していません。とは言え次の文書になんとなくまとまっています。

『HCL Sametime 11.0 Administrator Documentation』
https://help.hcltechsw.com/sametime/11.0.0/administrator_doc.html


公式のオンラインヘルプにある V10 の文書を参考にすることはできると思います。

『Sametime 10.0 Installation and Administration』
https://help.hcltechsw.com/sametime/10.0/index.html



V11 固有の機能について知りたい場合、カスタマーサポートのトップページから「Sametime 11 <知りたい事>」といった感じで検索してみて、さらに絞り込んでいくのも良いと思います。

https://support.hcltechsw.com/csm?id=csm_index




では、インストールしていきます。


ガイド中で Domino をインストールする項の冒頭に「Linux OS が "en_US" ロケールにインストールされていることを確認してください」(意訳)とボールド体で強調されている部分があります。ロケールを "ja_JP.UTF-8" で進めてしまった私は、のちのちドはまりすることになりました。少なくとも Sametime のインストール前には、次のコマンドでロケールを "en_US" に変えましょう。

> localectl set-locale LANG=en_US

ロケールを変えた後は念のためログインし直しましょう。
ロケールを変えずに進めるとどうなったかについては、後述します。

なお Domino のインストールについてガイドには手順が書かれていますが、インストールとセットとなるOS側の設定(ユーザーとグループを追加するなど)には触れられていません。「domino 11 centos install」でググるとヒットする海外の HCL Master のブログがありました。

ちなみに、Domino 11.0.1 のインストーラは、まっさらの環境に新規にインストールすることできます。


Sametime Community Server (以降「Sametime」と呼びます)では、Persistent Chat (永続的なチャット)が有効の状態でインストールされます。Persistent Chat は MongoDB (に格納された chat logging 情報)を利用します。そのため Sametime インストールの前に MongoDB のインストールを済ませておくことが必要です。ただし、Sametime インストール後はガイドの記載に従って Persistent Chat と MongoDB の要件を無効にすることができます。


という訳で先に MongoDB をインストールします。


MongoDB は yum(=パッケージ管理ツール)でインストールするのですが、MongoDB の最新バージョンではなく、サポートされている 3.6 というバージョンをインストールするために、ファイル mongodb-org-3.6.repo を作成しておきます。ここが私にとって一つ目のハマりポイントでした。

作成したファイルの内容はガイドに記載されていますので、それをコピペすることができます。内容の一部に、ページ幅で収まらず途中で改行されている長い1行があります。その行の右端にあるハイフンが、ペーストしたときに欠落する場合がありました。ハイフンが欠落したままだと yum によるインストールが失敗します。ご注意ください。

yum では MongoDB と依存関係にある他のパッケージを自動でインストールしてくれ、非常に便利です。



ガイドでは、インストールの後 MongoDB を起動します。私は Linux に慣れてないこともあり大文字小文字をガイドのとおりにタイプするよう注意しています。ガイドには次のコマンドの 1 文字目は大文字の S で記載されていますが、これでは MongoDB は起動しません。

Service mongod start

小文字の s に読み替えましょう。



次、めちゃくちゃ重要です。



ガイドに従い MongoDB の設定を進めていくと「db.createUser({」で始まるコマンドを実行する手順の前に、次の記述があります。

Exit the mongo shell (type ‘exit’) and restart the MongoDB server with ‘service mongod restart’ and then continue with the commands below -

【日本語訳】

mongo シェルを終了して('exit' と入力)、'service mongod restart' で MongoDB サーバーを再起動してから、以下のコマンドを実行します。

ここでは、MongoDB サーバーを再起動した後、「db.createUser({」で始まるコマンドを投入するのですが、コマンド投入の前には、

> mongo

の実行後、

> use admin

忘れずに実行しておきます。

ここで use admin を実行しない場合、作成されるユーザーが admin.sametimeUser ではなく test.sametimeUser となります。

「db.createUser({」で始まるコマンドを投入したあとに、admin.sametimeUser で作成されていることを確認するには、次のコマンドを投入します。

> mongo

> use admin

> db.system.users.find()


もし test.sametimeUser で作成されていた場合、次のコマンドで削除した後、admin に切り替えて作成しなおしましょう。

> mongo

> use test

> db.dropUser("sametimeUser")


ここで test.sametimeUser のまま進めてしまった私の環境では、MongoDB のログ(/var/log/mongodb/mongod.log)に認証関連のエラーが大量に記録されてしまい、たった8日間でファイルサイズが 24GB まで膨れ上がりました。ディスク容量が圧迫され、Domino の夜間タスク等で「空きが無い」ことに由来するエラーを頻発する事態となりました。



さらに導入を進めて MongoDB の設定が完了したら、いよいよ Sametime Community 11.0 FP1 のインストールです。
※Sametime Community 11.0 FP1 のインストーラは Sametime 11.0 がインストールされていない環境へのインストールが可能です。



インストーラパッケージを解凍すると「Server」サブディレクトリが作成され、その中にファイル install.bin が追加されています。このファイルでインストールを実行しますが、その前に install.bin があるディレクトリへ移動して、パーミッション(実行権限)を変更します。次のコマンドでパーミッションを変更できます。

> chmod 777 install.bin


この install.bin をオプションなしで実行すると、インストーラの GUI が起動します。

GUIのインストールを進めていくと、私の環境では、テキストが無く縦に3つのラジオボタンだけが表示される画面がありました。日本語のガイドには説明がありますが、上から Standard, Limited Use, Dynamic の三択です。



日本語のガイドには「HCL Sametime サーバーは LDAP を使用します」とありますが、次のブログにも書かれているとおり V11 は Domino ディレクトリだけで構成することも可能です。今回私は LDAP を使いませんでした。

https://hcljapan.co.jp/software/blog/why-you-need-to-upgrade-to-sametime-v11-right-now



インストールが成功すると、データディレクトリ直下にあるファイル  stsetup_exit_status.txt に 0 が入ります。

ロケールを "en_US" に変更してインストールすると書きましたが、私のように "ja_JP.UTF-8" のまま進めると、ファイル stsetup_exit_status.txt に 0 がセットされていても実はインストールに失敗している、といったことがありました。この問題は次の技術情報で公開されています。

『Installing Sametime Community Server in Linux fails with no error』
https://support.hcltechsw.com/csm?id=kb_article&sysparm_article=KB0078564


もし stsetup.log 内のエラーが合致する場合、上の技術情報に従い対応した後、Sametime を上書きインストールしましょう。



さて、Sametime のインストールまで終われば、クライアントから接続できそうです。



私は 接続を確認するクライアントとして、Notesクライアントに内臓の Sametime アドイン(右のサイドバーに「Sametime 連絡先」として表示されるやつ)を使いました。

このクライアントのデフォルトは Sametime サーバーへのアクセスにポート 1533/tcp を使います。そのためポート 1533/tcp を Linux(CentOS7) 側で開ける必要があります。
※この時点では、80/tcp, 443/tcp, 1352/tcp, 1533/tcp 等のポートを開けていました


Sametime のクライアントは Notesに内臓のアドイン以外にも、Webブラウザや iPhone/Android のアプリ、Windows/Mac へインストールするタイプのものがあります。使用するクライアントや機能によって使用するポートがいろいろあります。次のURLはV10の情報ですが参考になると思います。

『Ports to open in firewalls』
https://help.hcltechsw.com/sametime/10.0/plan/plan_portstoopeninfirewalls.html?hl=firewall



Sametime を起動するには、Dominoデータディレクトリにある ststart スクリプトを実行します。

> su notes

> ./ststart

実際は Domino が起動した時に、Domino のタスクのひとつ(notes.ini の servertasks= に追加されている staddin)として Sametime が起動します。

ststart スクリプトでは、Sametime の実行に必要な環境変数などを設定します。 Sametime の設定を変更して再起動しなければならない場合、Domino コンソールから quit を実行する、またはシェルから

> ./ststart stop

として停止させてから再度起動します。

Domino まで停止しなくて良い場合は、Domino コンソールから次のコマンドで終了と起動を行うほうが手間がありません。

tell staddin q

load staddin



Limited use ライセンスの場合は、機能制限を反映させるためにポリシーファイルを手動で変更します、との記載が次の技術情報にあります。

『Manual settings required for HCL Sametime 11 Limited Use after installation』
https://support.hcltechsw.com/csm?id=kb_article&sysparm_article=KB0075403


この他、ガイドにも、永続的なチャット(persistent chat)を許可する「ポリシー」を設定する方法が記載されてもいます。

これらポリシーの変更は、Domino データディレクトリ直下にあるファイル "policies.user.xml" を編集します。ガイドに記載のファイル名(...users.xml)は誤りですので検索にヒットしません。それから、Domino データディレクトリ下の policy ディレクトリにも同名のファイルがありますが、こちらは変更しないように。


policies.user.xml 内をポリシーの id で検索すると "im.v10sample.policy", "im.default.policy", "im.anonymous.policy" の3か所でヒットします。

"im.v10sample.policy" はコメントアウトされており無効です。

Webブラウザからの匿名アクセスを許可している場合に "im.anonymous.policy" が使用されます。ログインを前提とする場合は使用しません。

ちなみに、Domino ディレクトリに登録したグループ(のメンバー)へ適用するポリシーを設定することが可能との事。



MongoDB のログはデフォルトでは /var/log/mongodb/mongod.log に作成されます。前述のとおり私の環境では設定ミスにより肥大化する現象が発生しましたが、正しく設定された状態でもログファイルは mongod.log に追記される設定です。

MongoDBでは、ログをローテーションする設定が可能です。次の文書が参考になります。

https://docs.mongodb.com/manual/reference/command/logRotate/


ローテーションを設定すれば、コマンド発行によりログファイルを切り替え可能です。Sametime 稼働中にも切替できます。定期的にコマンド発行を実施することで、過去ログを圧縮したり古すぎるログを削除する、といった運用も可能と思います。



私は今回、GUIインストールとサイレントインストールのどちらも試しました。そのどちらにも Sametime のアンインストーラ uninstall.bin が存在しないのは私だけでしょうか...

【2020/5/11 追記】次の技術情報が公開されました。Linux 版の 11.0, 11.0FP1 ともにアンインストーラは無いようです...
How one can uninstalls Sametime v11/v11FP1 community server & then reinstalls it?
https://hclpnpsupport.hcltech.com/csm?id=kb_article&sysparm_article=KB0079104&sys_kb_id=31bbc8841bfcdc54c48197d58d4bcb14



Domino の起動直後、Domino コンソールに「重大: Failed to read from file」が表示されることがありますが、これは無視できるエラーらしいのですが、消すことができないようです。※SAME-32778 として問題が報告されています



Sametime Mux Server は、コネクションを管理できるものらしいのですが、ここでは不要なためインストールしませんでした。



Sametime 11.0 FP1 Proxy Server (以降「Proxy」と呼びます)のインストーラは、Sametime Communinty Server のとは別です。インストーラを解凍すると sametimeproxy サブディレクトリ内にファイル install.sh があります。これもパーミッションを変更しておきます。

> chmod 777 install.sh


Proxy のインストール時に "Sametime Server Host" や "Mongo Host" などを聞かれます。"Sametime Server Host" に FQDN を指定し、同一ホストにある "Mongo Host" にも同じ FQDN を指定したところインストールは失敗しました。その後、私の環境では setenv.sh に保存されていた "MONGO_HOST" の値を "127.0.0.1" と書き直し、再度インストールすることで成功しました。


Proxy Server までインストールが完了すると Web ブラウザやモバイルアプリから接続できます。※接続に必要なポートは firewall-cmd で追加しましょう



以上です。



検証環境の Sametime サーバーは、Windows 10 PC上の VMware Workstation 15 Player に作成した仮想マシンへ Linux(CentOS) を起動したものです。

iPad 上の Web ブラウザから PC 内のゲスト OS 上の Sametimeへアクセス

最終的には iPad にインストールした Sametime アプリから Windows 10 PC へ接続すると、仮想マシンへポートフォワーディングされ Sametime サーバーへアクセスできるようになりました。


iPad の Sametime アプリからPC内のゲストOS上の Sametime へアクセス


2020年3月30日月曜日

グループの入れ子レベル

ドミノディレクトリにグループを作成して、そのグループのメンバーとして別のグループ名を追加することがあります。

このように別のグループをメンバーに追加している状態をここでは「入れ子」と呼びますが、例えば次のように入れ子(ネストとも言う)のレベル(階層とも言う)が深くなった場合、どのレベルまでサポートされるかご存知でしょうか。

11.0 の Administrator ヘルプにある「Domino 命名規則」には(つい最近まで)次のように記載されていました。

メール配信では、グループを5つのレベルまで入れ子にできます。メール配信以外の目的では、6つのレベルまで入れ子にできます。

この制限がどのバージョンからあったかは不明ですが、ずいぶん前からあったように思います。

ところが、アクセス制御リストの画面にある「有効なアクセス権」ボタンを押して、あるユーザーのアクセス権を調べていた時「6つよりレベルが多いこと」に気付きました。

そこで、ドミノディレクトリへグループ文書を 20 作成して次のように設定しました。

グループ "Group1" のメンバー欄へ Group2 を追加
グループ "Group2" のメンバー欄へ Group3 を追加
グループ "Group19" のメンバー欄へ Group20 を追加
グループ "Group20" のメンバー欄へ Test User/v10 を追加

Group20 に追加したユーザー「Test User/v10」は入れ子のレベルが 20 です。

データベースの ACL へグループ "Group1" だけ追加して、「有効なアクセス権」ボタンから調べてみたところ、なんと「Test User/v10」はアクセスできそうでした。

実際に Test User/v10 がこのデータベースへアクセスすると、拒否されることなく開くことができました。


この結果をサポートへ報告してみたところ、次のことがわかりました。

  • メール配信時の入れ子の制限は、グループを Domino 側で展開する場合は制限が無く、クライアントから送信する場合は20レベル以上の階層はエラーになる
  • メール配信以外の入れ子の制限はなくなった
  • 入れ子の制限は変わっているが、ヘルプの更新がされないまま現在に至っている

制限が緩和されていたことを知りませんでした...

これを受けて、Notesクライアントでメールを作成して、宛先へ "Group1" を指定して送信してみたところ、20 レベルのユーザーのためエラーが表示され送信できません。


グループをクライアント側で展開しているためにエラーとなったようです。

次に、グループを Domino 側で展開させるために宛先を「Group1@v10」に変えて送信してみると、今度はエラーなしに送信できました。


さて、メール配信時の入れ子の制限はグループを展開する場所によって違うことを確認できましたが、Domino のメールへアクセスする方法はいくつかあります。どのアクセス方法が制限を受けるのでしょうか。

これまたサポートに聞いてみたところ、次の回答がありました。

【入れ子の制限なし:グループをDomino側で展開】
  • iNotes
  • Verse
  • Traveler
※CAA ではメールをブラウザ iNotes で開きますので入れ子の制限はありません

【入れ子の制限あり:グループをクライアントで展開、「グループ名@ドメイン名」の場合はDomino側で展開】
  • Standard版
  • Basic版
  • Nomad

入れ子と言えば、私が過去に書いた「グループの入れ子を洗い出す」というエントリがあるのですが、これも書き換えないと...

Nomad (iPad) は新元号に対応していました

iPad 版を皮切りに iPhone 版, Android 版もリリースされています「スマートデバイス対応Notes クライアント」とも言うべき HCL Nomad (以下 Nomad )について、新たに分かったことがありますので共有したいと思います。

Notes と Domino にも元号を表示する機能があるということで、昨年の改元に先立ち、新元号「令和」を表示するための対応を実施されたかたもいらっしゃると思います。 

改元のタイミング(2019年5月1日)で Nomad (当時は IBM Domino Mobile Apps 1.0.1 でした)が対応していたかどうかは、私は確認したという記憶が定かではありません。が、おそらく対応していなかったように思います。
※追記:サポートによるとiOS版 HCL Nomad は「1.0.5 から対応」とのこと

新たに分かったことというのは、Nomad でも「新元号が表示される」という事実です。

新元号に対応していない状態では、改元した日付を「平成 31年05月01日」と表示します。
対応している場合「令和 1年05月01日」と表示します。

今回 Nomad でも新元号を表示できることを確認しました。
下図は iPad の Nomad でのスクリーンショットです。

このビューの最初の列の値として「日付/時刻」タイプのフィールド「date1」を指定しています。その列では「年」の表示形式として "ggge" を指定しています。

上の図で「令和 1年05月01日」と表示されている文書を、Notesクライアントから文書のプロパティで見てみると、フィールド「data1」の値が 2019/05/01 であることがわかります。



ところで、私の iPad は、言語設定が「日本語」ですが、これを「英語」に変えると元号はどのように表示されるのでしょうか。

下図をご覧ください。最初のタブが「ホーム」ではなく「Home」と表示されているだけでなく、元号表示も変わりました。

元号は 「Reiwa」「Heisei」と表示されています!

年月日が漢字のままなのはご愛敬ですね。まあ Notes Standard でも「インターフェースの言語」を"英語"にすると同じ結果になるので...


もうひとつどうでもいい情報です。
元号表示は3桁表示まで対応しているようです。
西暦3017年は令和1000年に該当しますが、ggge での表示は「令和 *年」とアスタリスクに変換されてしまいました。

上の図は iPad の Nomad でのスクリーンショットですが、Notes クライアントでも同じ表示になりました。

2020年3月4日水曜日

セクションの境界線のスタイルを指定するには

LotusScript を使ってリッチテキストフィールドへセクションを追加したい場合があります。

次のコードのように NotesRichtextItem クラスの BeginSection メソッドを使うと、リッチテキストフィールドの最後に追加できます。
Dim ss As NotesSession
Dim dc As NotesDocumentCollection
Dim doc As NotesDocument
Dim body As NotesRichTextItem
Dim style As NotesRichTextStyle
Dim col As NotesColorObject

Sub Initialize
    Set ss = New NotesSession
    Set dc = ss.Currentdatabase.Unprocesseddocuments
    Set doc = dc.Getfirstdocument()
    Set body = doc.GetFirstItem( "Body" )
    
    Set col = ss.Createcolorobject()
    Call col.Setrgb( 0, 0, 255 )
    Set style = ss.Createrichtextstyle()
    style.Fontsize = 12
    style.Notescolor = COLOR_DARK_YELLOW
    
    Call body.Beginsection( "this is section title", style, col, True )
    Call body.Appendtext( "this is the string in the section" )
    Call body.Endsection()
    Call doc.Save( True, False )
End Sub

上のコードで追加したセクションは、下のように表示されます。

文書を編集モードに切り替え、セクションを選択した状態から「セクション」のプロパティを表示すると、「セクションタイトルと境界線」タブの中に「境界線」の「スタイル」という設定項目があります。※英語のプロパティ画面(下図)では Border の Style を指します


境界線の「スタイル」の選択肢は、現行バージョン(11.0)で11種類あります。

上のコードで追加したセクションの境界線の「スタイル」は、何も指定しない場合の(デフォルトの)スタイルになりました。

では、この境界線の「スタイル」は、どうやって指定できるのでしょうか。

BeginSection メソッドの第2パラメータでは NotesRichtextStyle のオブジェクトを指定できます。
Call NotesRichTextItem.BeginSection( title, titleStyle, barColor, expand )

けれども、このオブジェクトには境界線の「スタイル」に該当するものが見当たりません。境界線の「色」は、第3パラメータで指定が可能です

ちなみにセクションを扱う NotesRichTextSection クラスには、境界線の「スタイル」を設定したり取得できそうなメソッド/プロパティはありません。

どうやら標準のクラスでは、新たに作成するセクションの境界線の「スタイル」をデフォルトから変更したり、既存の境界線のスタイルを変更することができないようです。

それでは、このエントリで紹介した XML (Domino DTD = Domino文書型定義)を使う方法で新規に作成する場合はどうでしょうか。

まずは境界線のスタイルを変えて11種類のセクションを追加した文書を作成し、その文書を XML へ出力したものから、境界線のスタイル(borderstyle)の名前を調べてみました。

プロパティの表示
borderstyle
shadow
none
single
double
triple
twoline
windowcaption
gradient
tab
tabdiag


※表にあるスタイルの名前はこのヘルプ文書にも記載があります
※表の最下行の境界線は バージョン 8 で新たに追加されたスタイルらしいのですが、これはヘルプ文書に記載がありません。また XML へ出力しても borderstyle は設定されませんが、これは KKOOBM8D5V で報告されています。

出力した XML を参考に、borderstyle として tab を指定(21行目)したセクションを、ビューで選択している最初の文書へ追加してみます。

Dim ss As NotesSession
Dim db As NotesDatabase
Dim dc As NotesDocumentCollection
Dim doc As NotesDocument, tmpdoc As NotesDocument
Dim rtitem As NotesRichTextItem
Dim stream As NotesStream
Dim importer As NotesDXLImporter
Dim xml$, nid$

Sub Initialize
 Set ss = New NotesSession
 Set db = ss.CurrentDatabase
 
 xml = |





this is title string inner text
| '文書作成用のxmlをストリームへ書き込み、文書へ変換する Set stream = ss.CreateStream Call stream.WriteText( xml ) Set importer = ss.CreateDXLImporter( stream, db ) importer.DocumentImportOption = 2 'DXLIMPORTOPTION_CREATE Call importer.Process '変換した文書のリッチテキストフィールドの内容を選択文書へ追加する nid = importer.GetFirstImportedNoteId Set tmpdoc = db.GetDocumentByID( nid ) '変換した文書 Set dc = db.UnprocessedDocuments Set doc = dc.GetFirstDocument '選択文書 Set rtitem = doc.GetFirstItem( "Body" ) 'セクションを追加するリッチテキストフィールド Call rtitem.AppendRTItem( tmpdoc.GetFirstItem( "Body" ) ) Call doc.Save( True, True ) '変換した文書を削除する Call tmpdoc.Remove( False ) End Sub

実行後にビューで選択していた文書を開くと、下図のとおり tab スタイルのセクションを追加できていました。

既存のセクションの境界線のスタイルを参照したり変更できるプロパティとメソッドが欲しいので、アイデアとして投稿しました。ご賛同いただけるのであれば投票(Vote)してくださると嬉しいです。