はじめに
前編では、YoutubeAPIから取得したレスポンスを文書に登録することところまでできました。今回は本題であるサムネイル画像の取得とイメージリソースへの保存、ビューへの表示をやっていきます。 LotusScriptにはイメージリソースを操作する関数やクラスは用意されていませんが、DXL(Domino XML Language)を拡張することでイメージリソースの登録、削除が実装できるようになります。
DXL(Domino XML Language)って何?
DXL(Domino XML Language)は、ノーツ文書やノーツの設計要素をXMLとして出力、入力する機能です。例えばビューの設計を出力→変更→入力することで、ビューの色やフォントなど変えることができます。(頑張れば、既存の設計をなしにLotusScriptソースのみから設計要素を作成することもできます。)
【DXLとは】
- Dominoの文書や設計要素を、XMLフォーマットで出力したもの
- Domino文書型定義(Domino DTD)のタグ定義に従って出力される
- LotusScriptを使ってインポート、エクスポートができる
- NotesR6から利用可能
【参考】DXLを使ってビューをコピーする
DXLのサンプルとして、ビューの設計をコピーし、ビューの背景色を変更、新規ビューとして登録してみます。属性は一つ一つ調べる必要がありますが、スタイルシートのプロパティに近いものなので、HTMLやCSSを学んだことがある方は容易に理解出来ると思います。
【ソース】
Sub Click(Source As Button)
'---------- ---------- ---------- ---------- ----------
' ビューをDXLにエクスポート、背景色を変更、新しいビューとしてインポート
'---------- ---------- ---------- ---------- ----------
Dim session As New NotesSession
Dim db As NotesDatabase
Dim vw As NotesView
Dim d_doc As NotesDocument 'NotesViewの設計Document
Dim dxlExp As NotesDXLExporter
Dim domParser As NotesDOMParser
Dim domNode As NotesDOMDocumentNode
Dim domElm As NotesDOMElementNode
Dim dxlImp As NotesDXLImporter
Dim stream As NotesStream
Dim sUnid As String 'NotesViewのUNID
Dim iRet As Integer 'Msgbox戻り値
Set db = session.CurrentDatabase
Set vw = db.GetView("ApiSettingVw")
sUnid = vw.UniversalID 'NotesViewのUNIDを取得
Set d_doc = db.GetDocumentByUNID(sUnid) 'NotesViewのDocumentを取得
'実行確認
iRet = Msgbox("このボタンはDXLでビューをコピーするサンプルです。" & Chr(13) _
& "実行結果はDominoDesignerで確認してください。" & Chr(13) & "実行しますか?",1+16,"確認")
If iRet <> 1 Then
Exit Sub
End If
'DXLのエクスポート
Set dxlExp = session.CreateDXLExporter
Call dxlExp.SetInput(d_doc) 'ViewのDXLを取得
'DXL編集
Set domParser = session.CreateDOMParser()
Call domParser.SetInput(dxlExp) 'DXLを展開 '
Call dxlExp.Process
Set domNode = domParser.Document
Set domElm = domNode.DocumentElement 'DXLからViewの属性にアクセス
Call domElm.SetAttribute("name","API設定2")
Call domElm.SetAttribute("alias","ApiSettingVw2")
Call domElm.SetAttribute("bgcolor","red")
'DXLのインポート
Set stream = session.CreateStream()
Call domParser.SetOutput(stream) 'DOMParserの出力先を指定
Call domParser.Serialize 'DXLをStreamに出力
Set dxlImp = session.CreateDXLImporter
dxlImp.DesignImportOption = 2 '2-新規追加、5-更新
dxlImp.DocumentImportOption = 2 '2-新規追加、5-更新
Call dxlImp.Import(stream,db) '設計にインポート
Msgbox "Done."
End Sub
YoutubeAPIを使ってサムネイル画像をローカルにダウンロードする
さて本題に戻ります。YoutubeAPIのレスポンスから抽出したサムネイルURLからバイナリを取得し、画像として保存するサンプルコードを書いてみます。バイナリの保存は「ADODB.Stream」を使用します。NotesStreamクラスを使っても保存できるのですが、サムネイル画像が64Kを超えるとエラーが出ますので念のため「ADODB.Stream」を使います。
【ソース】
Sub Click(Source As Button)
'---------- ---------- ---------- ---------- ----------
'サムネイル画像のパスを指定し、取得したバイナリを画像として保存
'ADODB.Streamを使用(64k制限なし)
'---------- ---------- ---------- ---------- ----------
Const TMPPATH = "C:\tmp\" '画像の一時保存フォルダ
Dim sUrl As String 'サムネイル画像URL
Dim sFileName As String 'サムネイル画像名
Dim xml As Variant 'MSXML2オブジェクト
Dim fileStream As Variant 'ADOストリームオブジェクト
Dim sTmpFilePath As String 'サムネイル画像保存パス
sUrl = "https://i.ytimg.com/vi/6EKg0SpHflE/default.jpg"
sFileName = "6EKg0SpHflE.jpg"
'HTTP リクエストの実行
Set xml = CreateObject("MSXML2.ServerXMLHTTP.6.0")
xml.Open "GET", sUrl, False
xml.send ""
' HTTPステータスコードが200の場合 (成功) のみファイルを保存します
If xml.Status = 200 Then
Set fileStream = CreateObject("ADODB.Stream")
fileStream.Type = 1 ' バイナリ形式
fileStream.Open
fileStream.Write xml.responseBody ' レスポンスボディをStreamに書き込み
sTmpFilePath = TMPPATH & sFileName 'サムネイル保存パス
fileStream.SaveToFile sTmpFilePath, 2 'Streamをファイルとして保存
fileStream.Close 'Streamをクローズ
Set fileStream = Nothing
Else
Msgbox "HTTPリクエストが失敗しました。ステータスコード"
End If
Set xml = Nothing
'完了メッセージ表示
Msgbox "Done!"
End Sub
LotusScriptのDXLでイメージリソースを登録する関数
大阪研究会の浜さんに作成して貰ったスクリプトライブラリの関数一覧がこちらです。たくさんの関数が定義されていますが、利用するのは下記の3つだけです。
- ImageResource_New :イメージリソースの登録
- ImageResource_Remove :イメージリソースの削除
- InlineImage_Replace :リッチテキストフィールドへのイメージリソース表示
これらの関数を作成するにはかなり試行錯誤が必要です。でも、安心して下さい。許可を頂き、最後の方でこのライブラリを含む設計公開NTFダウンロードリンクを配置しています。
YoutubeAPIから取得したサムネイル画像をイメージリソースに登録する
上記関数を使って、ローカルに保存したサムネイル画像をイメージリソースに保存後、削除するコードを書いてみます。ここまでできれば「前編」のソースと合わせてYoutubeAPIからレコード、サムネイル画像を取得し、文書とイメージリソースに登録するLotusScriptは書けるかと思います。
【ソース】
Option Declare
Use "DXL_Tiny"
Sub Click(Source As Button)
'---------- ---------- ---------- ---------- ----------
'サムネイル画像のパスを指定し、取得したバイナリを画像として保存後、ImageResourceに登録
'ADODB.Streamを使用(64k制限なし)
'---------- ---------- ---------- ---------- ----------
Const TMPPATH = "C:\tmp\" '画像の一時保存フォルダ
Dim sUrl As String 'サムネイル画像URL
Dim sFileName As String 'サムネイル画像名
Dim xml As Variant 'MSXML2オブジェクト
Dim fileStream As Variant 'ADOストリームオブジェクト
Dim sTmpFilePath As String 'サムネイル画像保存パス
sUrl = "https://i.ytimg.com/vi/6EKg0SpHflE/default.jpg"
sFileName = "6EKg0SpHflE.jpg"
'HTTP リクエストの実行
Set xml = CreateObject("MSXML2.ServerXMLHTTP.6.0")
xml.Open "GET", sUrl, False
xml.send ""
' HTTPステータスコードが200の場合 (成功) のみファイルを保存します
If xml.Status = 200 Then
Set fileStream = CreateObject("ADODB.Stream")
fileStream.Type = 1 ' バイナリ形式
fileStream.Open
fileStream.Write xml.responseBody ' レスポンスボディをStreamに書き込み
sTmpFilePath = TMPPATH & sFileName 'サムネイル保存パス
fileStream.SaveToFile sTmpFilePath, 2 'Streamをファイルとして保存
fileStream.Close 'Streamをクローズ
Set fileStream = Nothing
'ImageResourceに登録
Call ImageResource_New("tmpimage", sTmpFilePath)
'一時フォルダのサムネイルを削除
If Not Dir$(sTmpFilePath,0) = "" Then
Kill sTmpFilePath
End If
Else
Msgbox "HTTPリクエストが失敗しました。ステータスコード"
End If
Set xml = Nothing
'完了メッセージ表示
Msgbox "Done!"
End Sub
サムネイルを表示するビューの開発
Notesビューではサムネイル画像の高さに応じて高さを変更することはできないため、行の高さを「4行」に設定します。
文書の削除時にイメージリソース内のサムネイル画像を削除する
これでYoutubeAPIから取得したレコードを使って、文書を登録、ビューにサムネイルを表示するプログラムを作ることができました。実運用するには文書を削除した際に、関連するイメージリソースも消えて欲しいです。そこで「データベーススクリプト」の「Postdocumentdelete」イベントで削除対象文書に関連するイメージリソースを削除するコードを書きます。
【ソース】
Sub Postdocumentdelete(Source As Notesuidatabase)
On Error Goto ErrRtn
'---------- ---------- ---------- ---------- -----------
'文書が削除される前にImageResourceを削除する
'引数 :Source-現在のUIデータベース
'---------- ---------- ---------- ---------- -----------
'クラス・変数宣言
Dim db As NotesDatabase
Dim dc As NotesDocumentCollection
Dim doc As NotesDocument
Dim sResourceName As String '削除対象リソース名
'クラス、変数セット
Set db = Source.Database
Set dc = Source.Documents '削除対象文書のCollectionを取得
'削除対象文書がなくなるまでループ
Set doc = dc.GetFirstDocument
While Not(doc Is Nothing)
sResourceName = doc.ThumbnailIcon(0)
Call ImageResource_Remove(sResourceName)
Set doc = dc.GetNextDocument(doc)
Wend
Print "delete ResourceFile:" & Cstr(dc.Count)
Exit Sub
ErrRtn:
Msgbox Error() & Chr(13) & "Line: " & Erl(), 16, "Error"
Print Error(), "ErrorCode: " & Err(), "Line: " & Erl()
Print "モジュール: PostDocumentDeleteでエラーが発生しました。"
End
End Sub
設計公開NTFのダウンロード
今回のブログで紹介したコードを含む設計公開NTFをアップロードしましたので、必要に応じてご活用下さい。YoutubeAPIのAPIKEYは含んでおりませんので、各自で取得し、設定文書に登録して頂く必要があります。
【ダウンロードリンク】
youtube.zip
最後に
YoutubeAPIからの情報取得を応用すれば他のWebAPI(ChatGPTなど)とも連携できるようになりますし、イメージリソースの登録がLotusScriptからできるようになれば、製品イメージや、在庫の保管場所マップ、不良箇所イメージなどもビューから見ることができ、Notesクライアントの活用シーンが広がります。Notesクライアントで表示できると言うことはNomadWebやNomadMobileでの表示もできますので、今までできないと思っていた業務改善が実現できるのではないかと思います。
【参考リンク】
ノーツコンソーシアム大阪研究会 浜さんブログ
出直し!! ドミノ塾 (denaoshidomino.com)