はじめに
前回、タスク管理を再検討するという話を書きました。hkob.hatenablog.com
これを実現するために、NotionRubyMapping に append_block_children を実装しました。あとは、update_block や delete_block などを実装する必要がありますが、この検討をした上で必要なところから実装していこうと思います。この際、NotionRubyMapping に追加で実装した機能はここで紹介してみます。適宜キリのいいところでリリースしますが、一部未リリースの機能を使っている場合もあります。
仕様が大きく一回の記事では終わりそうもないので、何回かに分割して公開します。今回は、まず synced block の自動差し替えを実装することにします。なお、スクリプトは冪等性があるものとして、特に変更なければ何も実行せず、ページなどが更新されていれば、適宜関連するブロックが更新される仕組みを目指します。
作業1. タスク一覧ページを取得または作成
マエダさんのメソッドでは、その日が終わったらブロックをデータベースにドラッグすることでページに変更していました。この処理は API では難しいので、Synced block を活用することにします。
まずは毎日のタスクデータベースに今日のタスク一覧ページを作成します。存在しない場合には、自動生成します。今はデータベースは空の状態です。
処理の最初はこちらになります。NOTION_API_KEY の登録から始まり、上記のデータベースから今日の「タスク一覧ページ」を取得します。今回の場合には存在していないので、create_child_page
で日付から作成されます。日付欄があるので、タイトルに日付を付けるのもどうかとは思いますが、タイトルには興味はないので、このままでいきます。
#!/usr/bin/env ruby require "notion_ruby_mapping" include NotionRubyMapping # NotionCache シングルトンを生成し、NOTION_API_KEY を登録 NotionCache.instance.create_client ENV["NOTION_API_KEY"] #### 1. タスク一覧ページを取得または作成 # 今日を取得 today = Date.today today_str = "#{today.strftime("%-m月%-d日")}(#{%w[日 月 火 水 木 金 土][today.wday]})" # 「毎日のタスク」データベースを取得 dt_database = Database.find "0bcdd69abaa6471683a0d54e28577900" # 日付プロパティを取得 dp = dt_database.properties["日付"] # 日付が今日の「タスク一覧ページ」を取得 today_dt = dt_database.query_database(dp.filter_equals(today)).first # 存在しなかった場合には、今日の「タスク一覧ページ」を作成 today_dt || = dt_database.create_child_page do |_, pc| pc["名前"] << today_str pc["日付"].start_date = today end
このプログラムを実行したところ、毎日のタスクが生成されました。なお、冪等性からもう一度実行しても、今作成したページがそのまま取得できるだけです。明日になると新しいページが作成されます。
作業2. タスク一覧ページの Synced block を取得または作成
今作成したページを覗くと空のページになっています。
このページは Synced block の親ページになります。ページの children を調べて synced block がなければ作ります。ブロックがオリジナルの synced_block なのかを調べるメソッド synced_block_original?
を追加しました。
#### 2. タスク一覧ページの Synced block を取得または作成 # タスクページ一覧の Synced block を取得 synced_block_original = today_dt.children.select(&:synced_block_original?).first # 存在しなかった場合には、オリジナルの Synced block を作成。中身は日付文字列だけ書いておく。 synced_block_original ||= today_dt.append_block_children( Block.new.synced_block(sub_blocks: [Block.new.paragraph(today_str)]), )
実行すると synced block が作成されました。二回目の実行では、すでに取得済の synced_block が取得されていることも確認しています。
作業3. 今日のタスク Synced block の差し替え
今日のタスクは先ほどのタスク一覧の Synced block のコピーが置かれる予定です。日付が変わったら、この Synced block を削除して、先ほど作ったものに置き換えたいと思います。今日のタスクは見出し1のトグルブロックになっていて、この ID で子供を検索することにします。
まずはトグルブロックの子供を全て取得します。その後、子供の中に先ほどの Synced block があるかを確認します。あった場合には何もせずに終了します。なかった場合には、存在している子供のブロックを全部消して、先ほどの synced block のコピーを作成します。まだ、Block の削除を作成していなかったので、NotionRubyMapping に機能を追加します。API の名前は delete block ですが、Rails を使っている人は destroy の方が馴染み深いと思うので、メソッド名は destroy の方にしました。
#### 3. 今日のタスク Synced block の差し替え # トグルブロックを取得 toggle_block = Block.find("f1b63bd647cd4d76b8086f5e4cd161ba") # トグルブロックの子供の ID を全部取得 toggle_children = toggle_block.children # Synced block のオリジナルの id を取得し、それが今日のものならスキップ unless toggle_children.map(&:synced_block_original_id).include? synced_block_original.id # 今日のものでなければトグルブロックの子供を全部削除 toggle_children.each do |block| block.destroy end # 今日の Synced block に置き換え toggle_block.append_block_children Block.new.synced_block(block_id: synced_block_original.id) end
実行すると以下のように Synced block が差し替えられました。2回目は差し替えられずにそのまま残っていました。実装をモタモタしていたので、すでに1日ずれてしまいましたね。