LoginSignup
4
2

Kindleの本をPower BIとPower Appsで可視化する

Posted at

はじめに

先日、下記の記事を拝読し、
Kindleってデスクトップアプリを入れると、xmlで書籍データが蓄積されるんだ!
と衝撃を受けました。

記事では

  1. PythonXMLをパース
  2. Power BIで可視化

というアプローチをとっています。

私はPower Apps Loverとして、Power Appsで表現する方法を考えてみました。

1. 書籍データを取得する(XMLのパース)

詳しくは紹介した記事を是非読んでいただきたいです。
Kindleのデスクトップアプリをインストールすると、\AppData\Local\Amazon\Kindle\Cache\XMLファイルが自動保存されます。

XMLパス
C:\Users\user_name\AppData\Local\Amazon\Kindle\Cache\KindleSyncMetadataCache.xml

こちらをPower BI Desktopでパースします。

image.png

標準でXMLはデータとして読み込むことができます。

  • 本のタイトル
  • 著者
  • 出版社
  • 購入日
  • 出版日
  • データのタイプ

読み込むと上記のようなデータが取れるようです。
Power Query式で下記のように読み込みます。

Power Query式
let
    // XMLファイルをテーブルに読み込む
    Source = Xml.Tables(File.Contents("C:\Users\{user_name}\AppData\Local\Amazon\Kindle\Cache\KindleSyncMetadataCache.xml")),
    
    // "add_update_list"列を展開して"meta_data"を含める
    ExpandedAddUpdateList = Table.ExpandTableColumn(Source, "add_update_list", {"meta_data"}, {"meta_data"}),
    
    // "meta_data"列を展開して各種の詳細を含める
    ExpandedMetaData = Table.ExpandTableColumn(ExpandedAddUpdateList, "meta_data", {"ASIN", "title", "authors", "publishers", "publication_date", "purchase_date", "textbook_type", "cde_contenttype", "content_type", "origins"}, {"ASIN", "title", "authors", "publishers", "publication_date", "purchase_date", "textbook_type", "cde_contenttype", "content_type", "origins"}),
    
    // "title", "authors", "publication_date"などのネストされた列をさらに展開
    ExpandedTitle = Table.ExpandTableColumn(ExpandedMetaData, "title", {"Element:Text", "Attribute:pronunciation"}, {"Title_Text", "Title_Pronunciation"}),
    ExpandedAuthors = Table.ExpandTableColumn(ExpandedTitle, "authors", {"author"}, {"Author"}),
    ExpandedPublicationDate = Table.ExpandTableColumn(ExpandedAuthors, "publication_date", {"Element:Text"}, {"PublicationDate"}),
    ExpandedPublishers = Table.ExpandTableColumn(ExpandedPublicationDate, "publishers", {"publisher"}, {"Publisher"}),
    ExpandedPurchaseDate = Table.ExpandTableColumn(ExpandedPublishers, "purchase_date", {"Element:Text"}, {"PurchaseDate"}),
    ExpandedTextbookType = Table.ExpandTableColumn(ExpandedPurchaseDate, "textbook_type", {"Element:Text"}, {"TextbookType"}),
    ExpandedOrigins = Table.ExpandTableColumn(ExpandedTextbookType, "origins", {"origin"}, {"Origin"}),
    ExpandedOriginType = Table.ExpandTableColumn(ExpandedOrigins, "Origin", {"type"}, {"OriginType"}),
    
    // 最終出力用に必要な列だけを選択
    SelectedColumns = Table.SelectColumns(ExpandedOriginType,{"ASIN", "Title_Text", "Title_Pronunciation", "Author", "Publisher", "PublicationDate", "PurchaseDate", "content_type", "OriginType"}),
    SelectRows = Table.SelectRows(SelectedColumns, each ([Title_Text] <> "" and [Title_Text] <> "---------------" and [ASIN] <> "B003ODIZL6")),
    
    // 日付列のデータ型を正確な処理のためにdatetimeに変更
    ChangedType = Table.TransformColumnTypes(SelectRows,{{"PublicationDate", type datetime}, {"PurchaseDate", type datetime}, {"ASIN", type text}, {"Title_Text", type text}, {"Title_Pronunciation", type text}, {"Publisher", type text}, {"content_type", type text}, {"OriginType", type text}}),
    ReplaceErrorValues = Table.ReplaceErrorValues(ChangedType, {{"OriginType", null}})
in
    ReplaceErrorValues

その他、データを整形するとこのようにできます。

image.png

ビューの作成であれば、Power BIで全て完結します。
スキーマの設定やビューの作成は、この記事では取り扱いません。

一旦ここまでで、発行を実行します。

image.png

2. Power Appsで書籍データを取得する

Power BI(SaaS)に発行されたデータセットは、Power Appsで直接取得することができます。

データの接続からPowerBIを選択します。
PowerBIコネクタから直接テーブルを取得し、テーブルギャラリーのデータソースとすることはできないので、一度ボタンクリックを通じて、コレクションとして評価します。

活用するアクションはPowerBI.ExecuteDatasetQueryです。

面白い

Power BIのデータセットを読み込む

OnSelect
// 1. Set Context
UpdateContext(
    {
        GroupID: "---",
        DatasetID: "---",
        Query: "EVALUATE 'Main'" // 先は全行抽出するDAXクエリ式
    }
);

// 2. Evalute query
ClearCollect(queryResults,
    ForAll(PowerBI.ExecuteDatasetQuery(GroupID,DatasetID,Query).firstTableRows,
        {
            ASIN: Text(ThisRecord.Value.'Main[ASIN]'),
            Title: Text(ThisRecord.Value.'Main[Title_Text]'),
            Publisher: Text(ThisRecord.Value.'Main[Publisher]'),
            PublicationDate: DateTimeValue(ThisRecord.Value.'Main[PublicationDate]'),
            PurchaseDate: DateTimeValue(ThisRecord.Value.'Main[PurchaseDate]'),
            OriginType: Text(ThisRecord.Value.'Main[OriginType]'),
            Authors: Text(ThisRecord.Value.'Main[Authors]')
        }
    );
);

とても面白い事象ですが、Power BIのデータセットを読み込むだけでは、データ型を含めてコレクションに格納することはできないようです。

image.png

ParseJSON関数で文字列を評価した時のように、UntypedObject型と評価されてしまいます。

上記の現象の対策として、ForAll関数でデータ型を変換しています。

アプリを作り上げる

こんな感じでレイアウトを整えます。

image.png

モダンコントロールのテーブルを採用していますが、そちらについては下記の記事が参考になります。

Power AppsのスクリーンのOnVisibleでデータの取得を実施

OnVisible

UpdateContext(
    {
        varSortOrder: SortOrder.Ascending
    }
);
// 1. Set Context
UpdateContext(
    {
        GroupID: "---",
        DatasetID: "---",
        Query: "EVALUATE 'Main'"
    }
);

// 2. Evalute query
ClearCollect(queryResults,
    ForAll(PowerBI.ExecuteDatasetQuery(GroupID,DatasetID,Query).firstTableRows,
        {
            ASIN: Text(ThisRecord.Value.'Main[ASIN]'),
            Title: Text(ThisRecord.Value.'Main[Title_Text]'),
            Publisher: Text(ThisRecord.Value.'Main[Publisher]'),
            PublicationDate: DateTimeValue(ThisRecord.Value.'Main[PublicationDate]'),
            PurchaseDate: DateTimeValue(ThisRecord.Value.'Main[PurchaseDate]'),
            OriginType: Text(ThisRecord.Value.'Main[OriginType]'),
            Authors: Text(ThisRecord.Value.'Main[Authors]')
        }
    );
);

モダンコントロールのテーブルのItemsプロパティは、条件に応じて値の表示を変化させます。

Items
Sort(
    Search(
        If(
            And(!IsBlank(cmbPublisher.Selected.Value),!IsBlank(cmbOriginType.Selected.Value)),
            Filter(queryResults,
                Publisher=cmbPublisher.Selected.Value,
                OriginType=cmbOriginType.Selected.Value
            ),
            !IsBlank(cmbPublisher.Selected.Value),
            Filter(queryResults,Publisher=cmbPublisher.Selected.Value),
            !IsBlank(cmbOriginType.Selected.Value),
            Filter(queryResults,OriginType=cmbOriginType.Selected.Value),
            queryResults
        ),
        inpSearch.Value,"Title"
    ),
    PurchaseDate,
    varSortOrder
)

これで、それらしいビューはできます。

image.png

Power BIでできることをわざわざAppsでやっているだけで本当に意味はないです。

【応用】Power Appsならでは!を加える

Kindle for desktopで作成されるXMLでは、読み込めるデータに限りがあります。

  • ASINコード
  • 本のタイトル
  • 著者
  • 出版社
  • 購入日
  • 出版日
  • データのタイプ

そしてXMLのデータを読み込んで、Power Appsで表示するだけでは芸がない。

せっかくなので画像や詳細をAPI経由で集めたい!
その方法を模索していこうと思います。

ASINコードを使うハードルが高い…

XMLでASINコードを取得できています。

ASINコード(Amazon Standard Identification Number) は、Amazonが商品識別に使用するコードとのこと。

Amazonのコードなので、Amazon Product Advertising API 5.0が使えそう!

と思いましたが、何やら利用のハードルが高く、私は今、使用する条件が満たせませんでした(´;ω;`)

本の検索で対処してみる

今回はKindle本なので、本を検索するAPIであれば対処できるのでは!?と思い、Google Books APIを使ってみることにしました。

本の情報検索のみであれば認証も不要のAPIです!

過去にもトライしていました。

カスタムコネクタを作って、Power AppsからAPIを使えるようにします。

カスタムコネクタの作成

カスタムコネクタの概要は下記をご覧ください。

今回は本の検索機能に絞って作成します。

  1. Power Automate > カスタムコネクタ
    image.png
  2. 「一から作成」を選択
    image.png
  3. コネクタ名を設定(好きな名前をつけてください)
    image.png
  4. ホスト名とベースURLを設定
    1. ホストwww.googleapis.com、ベースURL「/」
      image.png
  5. セキュリティは認証なし
    image.png
  6. 定義はアクション名とイコールです。GetBooksDataとつけました
    image.png

7.「要求」の設定

要求はサンプルからのインポートで実施します。

動詞はGET
URLに下記を設定します。

https://www.googleapis.com/books/v1/volumes?q=夏目漱石&maxResults=10&startIndex=0

image.png

この画面になっていればOK!!

image.png

8. テスト

  1. コネクタの更新 - この操作を実施しないとテストが実施できません
  2. + 新しい接続
  3. テスト操作を実施
    image.png

テストが完了したら成功です!
image.png

Power Appsにカスタムコネクタ機能を加える

準備ができたので、モダンコントロールのテーブルOnSelectを実施したレコードで、Google Books APIを実施し、検索結果を表示する画面を作ります。

image.png

👆こんなイメージ

紹介したようせいさんのブログにも記載がありますが、モダンコントロールのテーブルのOnSelectが不安定です

安定的に動かしたいときは、ギャラリーコントロールが無難かもしれません

一旦うまくいくレコードで実行した例を紹介します。

カスタムコネクタを追加・実行

[データ] > [+ データの追加] > カスタムコネクタを追加します。

image.png

これによって、Power Appsからカスタムコネクタで定義したアクションが実行できます。

カスタムコネクタの呼び出しは、OnSelectで検索結果画面に行った後、検索結果画面のOnVisibleで下記を実行します。※ここら辺は好きな形で書いてください。

If(!IsBlank(ResultTable.Selected),
    ClearCollect(colGoogleBooks,
    Table(
        GoogleBooksSearch.GetBooksData({q:ResultTable.Selected.Title,maxResults:10,startIndex:0}).items)
    )
);

結果は赤枠のギャラリーに格納します。

image.png

ギャラリーに配置するコントロールのプロパティ

カスタムコネクタで取得したデータを配置するために、タイトルサブタイトルイメージコントロールは下記の通り設定しています。

  • タイトル
Text(ThisItem.Value.volumeInfo.infoLink)
  • サブタイトル
Text(ThisItem.Value.volumeInfo.publisher)
  • イメージコントロール
Text(ThisItem.Value.volumeInfo.imageLinks.thumbnail)

型の評価が曖昧になっているからですね…。
カスタムコネクタによって、Google Booksの検索結果のURLISBNコードも取得できるので、私が使っている読書管理アプリに登録するにも一役買いそうです。

APIを縦横無尽に楽しむうえではPower Platformはやはり最高のツール。検証が止まりません。

おわりに

今回はPower Appsで無理やり表現しましたが、Power BIでできることはPower BIでやったほうがスマートです。

image.png

こんな感じで映えます。
あくまでPower Appsでも表現できるんだなーくらいに見てもらえれば幸いです。

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2