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 も同時にリリースした。
ふと思い立ち NotionTimeRecording のコマンドライン版を作った。st: タスク開始、ot: タスク表示、et: タスク終了。タスクが一つしかない時は選択する必要なしにした。リターンキーだけ打てば一番古いものが対象になる。かなり便利になった。#notion #notionapi pic.twitter.com/9YOlmBaLLo
— hkob|Notion Ambassador (@hkob) 2022年11月12日
5. おわりに
NotionRubyMapping があると、この程度のプログラムは気楽に書けますね。今後もちょっとした小ネタを記事にしていきます。