コマンドライン版 NotionTimeRecording の作成: Notion 解説 (67)

1. はじめに

以前、NotionTimeRecoring というショートカット作成記事を書きました。新規タスクを開始時にタスク開始時間を記録し、既存のタスクを選んだ場合にはタスク終了時間を記録し、完了もチェックするものです。 hkob.hatenablog.com

結構便利で使っていたんですが、いちいちメニューからカーソルで選ぶのも面倒だなと感じていました。大体の作業は MacBook からやっていますし、基本的にターミナルは開いているので、コマンドラインで処理できると楽です。そこで、NotionTimeRecording のターミナル版を作成することにしました。なるべく処理わけをしたくないので、タスク開始のためのコマンド st とタスク終了のためのコマンド et を作ります。また、現在作業中のタスクのページを開く ot コマンドも用意することにします。

2. タスク開始コマンド st の作成

当然ながら NotionRubyMapping を使います。st コマンドは以下のようになりました。引数で与えられた文字列をタイトルとし、現在時刻を日付に登録したページを作成しているだけです。作成できたページの URL から URL scheme で Notion アプリを開いています。タスク更新がされているので、NotionTimeRecording の touch_file.txt を作成しています。常に起動し続けている MacBook が、このフォルダをフォルダアクションで見張っており、自動的に TaskUpdate スクリプトを自動起動します。

#!/usr/bin/env ruby
# frozen_string_literal: true
require "date"
require 'fileutils'
require "notion_ruby_mapping"
include NotionRubyMapping
NotionCache.instance.create_client ENV["NOTION_API_KEY"], wait: 0

DATABASE_ID = "私のタスクデータベースのID"
TOUCH_FILE = "#{ENV["HOME"]}/Dropbox/NotionTimeRecording/touch_file.txt"

if ARGV.empty?
  puts "Usage: st タスク名"
  exit
end

page = Database.find(DATABASE_ID).create_child_page do |p, pp|
  pp["日付"].start_date = DateTime.now
  pp["タスク名"] << ARGV.join(" ")
end

url = page["url"].gsub "https", "notion"
system("open #{url}")
FileUtils.touch TOUCH_FILE

Task update スクリプトについては、以下の記事で書いています。 hkob.hatenablog.com

3. タスク表示コマンド ot の作成

次にタスクを表示するコマンドを作ります。最初に今日の未完了のタスク一覧を取得します。未完了のタスクが一つだけであれば、尋ねることなくそのページを表示します。二つ以上の候補がある場合には、古い順に表示をして、その番号を入力することにします。基本的には一番古いものを選択すると思うので、単にリターンだけをタイプすると一番先頭のものが表示できるようになっています。

#!/usr/bin/env ruby
# frozen_string_literal: true
require "date"
require "notion_ruby_mapping"
include NotionRubyMapping
NotionCache.instance.create_client ENV["NOTION_API_KEY"], wait: 0

DATABASE_ID = "私のタスクデータベースのID"

db = Database.find DATABASE_ID
pps = db.properties
dp, cp = pps.values_at *%w[日付 Done]
query = dp.filter_equals(Date.today)
          .and(cp.filter_equals false)
          .ascending(dp)
pages = db.query_database(query).to_a

case pages.count
when 0
  puts "There are no tasks."
  exit
when 1
  page = pages.first
else
  pages.each_with_index do |apage, i|
    puts "#{i}: #{apage.title}"
  end
  num = gets.to_i
  page = pages[num] # 番号指定ミスのチェックはしない
end

url = page["url"].gsub "https", "notion"
system("open #{url}")

3. タスク終了コマンド et の作成

et はほぼ ot と同じで、page 更新が追加されているだけです。

#!/usr/bin/env ruby
# frozen_string_literal: true
require "date"
require "fileutils"
require "notion_ruby_mapping"
include NotionRubyMapping
NotionCache.instance.create_client ENV["NOTION_API_KEY"], wait: 0

DATABASE_ID = "私のタスクデータベースのID"
TOUCH_FILE = "#{ENV["HOME"]}/Dropbox/NotionTimeRecording/touch_file.txt"

db = Database.find DATABASE_ID
dps = db.properties
dp, cp = dps.values_at *%w[日付 Done]
query = dp.filter_equals(Date.today)
          .and(cp.filter_equals false)
          .ascending(dp)
pages = db.query_database(query).to_a

case pages.count
when 0
  puts "There are no tasks."
  exit
when 1
  page = pages.first
else
  pages.each_with_index do |apage, i|
    puts "#{i}: #{apage.title}"
  end
  num = gets.to_i
  page = pages[num] # 番号指定ミスのチェックはしない
end

pps = page.properties
pps["日付"].end_date = DateTime.now
pps["Done"].checkbox = true
page.save

url = page["url"].gsub "https", "notion"
system("open #{url}")
FileUtils.touch TOUCH_FILE

4. 動作確認

動作している様子を Twitter に貼ってみた。うまく動いていることを確認した。実は今回のプログラムで、end_date だけを設定する際にクラスが違うと設定できない不具合があった。その他いくつか修正した部分もあったので、それを改善した NotionRubyMapping v0.6.8 も同時にリリースした。

5. おわりに

NotionRubyMapping があると、この程度のプログラムは気楽に書けますね。今後もちょっとした小ネタを記事にしていきます。


hkob.notion.site