タスク管理の再検討(6) 今週のタスクを追加 : Notion 解説 (56)

1. はじめに

残った今週のタスクですが、これまでのものがかなり流用できたので、簡単に実装できてしまいました。これまでに大体説明した内容なので、コードだけ簡単に示します。

2. 実装

2.1 this_week_each_tasks

このメソッドは明日から1週間分のタスクのリストを取得するメソッドです。NotionRubyMapping を更新したので、日付を渡した場合にも日本のタイムゾーンで検索できるようになりました。

# @param [NotionRubyMapping::Database] db タスクデータベース
# @param [Date] today 今日の日付
# @return [NotionRubyMapping::List] タスクページのリスト(1週間以内)
def this_week_each_tasks(db, today)
  dp = db.properties["日付"]
  cp = db.properties["Done"]
  query = cp.filter_equals(false).and(dp.filter_after(today)).and(dp.filter_before(today + 8)).ascending dp # クエリを準備
  db.query_database query # 明日から1週間後までの未完了のタスクを古い順に取得
end

2.2 date_offset_str

タスクページの日付プロパティの開始時刻から「X日後: 」の文字列を作成するだけのメソッドです。ハマったのは日付の引き算をすると有理数が出てしまうので、to_i で整数に変換していることくらいでしょうか。

# @param [NotionRubyMapping::Page] date
# @return [String] 「X日後」の文字列
def date_offset_str(page)
  "#{(Date.parse(page.properties["日付"].start_date) - Date.today).to_i}日後: "
end

2.3 update_this_week_todos

今週のタスクを更新するメソッドです。tb は表示先の ToggleHeading2Block、et_tasks は明日から1週間分のタスクのリスト、td_hash は登録済のタスクページ id から ToDoBlock を引く辞書です。ここでは、大きく分けて3つの処理をしています。

  1. 未登録タスクの登録: 1週間分のタスクページ一覧(et_tasks)のうち、未登録のものだけ新規に ToDoBlock を追加します。
  2. X日後の文字列更新: 日付が変わるとX日後の文字列が一つ減ります。テキストを調べ、文字列が異なる場合には RichTextArray を差し替えます。
  3. 古いものを削除: 今日のタスクに移動してしまったものは、ここに表示する必要がないので、削除します。メンションされていない手書きの ToDo は削除しません。
# @param [NotionRubyMapping::ToggleBlock] tb
# @param [NotionRubyMapping::List] et_tasks
# @param [Hash<String=>NotionRubyMapping::ToDoBlock, String>] td_hash タスクページと To Do ブロックのハッシュ
def update_this_week_todos(tb, et_tasks, td_hash)
  todos = et_tasks.reject { |task| td_hash[task.id] }.map do |task| # タスクがすでに登録されていたらスキップ
    ToDoBlock.new(
      [
        date_offset_str(task), # X日後: という文字列
        MentionObject.new("page_id" => task.id, "plain_text" => task.title) # タスクページへのメンションを To Do を追加
      ]
    )
  end
  tb.append_block_children(*todos) if todos.count > 0 # 追加するべきものがあれば、Toggleブロックの子供として追加

  # すでに登録済のタスクの文字列をチェック
  et_tasks.select { |task| td_hash[task.id] }.each do |task|
    todo = td_hash[task.id] # 対応する todo を取得
    do_str = date_offset_str(task) # X日後の文字列を作成
    unless todo.rich_text_array[0].text == do_str # 文字列が異なった場合は書き換え
      todo.rich_text_array.rich_text_objects = [
        do_str,
        MentionObject.new("page_id" => task.id, "plain_text" => task.title)
      ]
      todo.save # 新しい文字列に更新
    end
    td_hash.delete task.id # ハッシュから削除
  end
  # 上記の処理で処理されなかったメンションページは今日のタスクに移動済のはずなので削除 (直接書いたものは残す)
  td_hash.each_value.reject { |todo| todo == "no_mention" }.each(&:destroy)
end

3. 終わりに

実行するとこんな感じになりました。今のところ授業くらいしか入っていないので、もっとちゃんとタスクを入れてみようと思います。NotionTimeRecording を使うようになったので、タイムラインビューを入れるようにしてみました。GTD でできるタスクをどんどん消化していくので、今日のタスクがどうしてもどんどん増える形になるのかなと思います。

今週のタスク & タイムライン

あとは、今週報があまりうまく活用できていないので、毎日のタスクの Synced block を自動的に週報にまとめるスクリプトが作れるといいですね。あとは中期のタスクに日付が入っていないものを一括で登録するとかしても面白いかもしれません。


www.notion.so