Ubuntu Weekly Recipe

第357回2015年の目標をUbuntuで管理しよう

ここだけの話なのですが、実はもう2015年が始まっているそうなんです。⁠一年の計は元旦にあり」とも言いますし、今回はUbuntuを使った目標管理ツールについて紹介しましょう。

目標管理? タスク管理? スケジュール管理?

読者の皆さんはどのように人生の目標をたて、目標達成に必要なタスクを洗い出し、そのタスクを確実に消化していくためのスケジュールを作っているのでしょうか?

たとえばこの記事を書いている人の場合、そもそも目標はその場の思いつきで決まります。必要なタスクはそのときの気分で決めて行きます。そしてそのタスクは消化されることなく、次の日には目標と一緒に忘れ去られることになります。よって目下のところ目標達成のために必要なのは「目標を忘れないこと」「⁠⁠目標を忘れないこと』を覚えておくこと」と言えます[1]⁠。

忘れないためには「メモる」ことが重要です。しかもできるだけ日々目にする何かに書いてある必要があります。現代人が日々目にするとなると、最初に挙がってくるのがWebブラウザーやスマートフォンです。そんなわけでモバイルにも対応したブラウザーベースの目標管理ツールはいろいろと存在します。たとえば有名どころだとLifetickがありますし、Goalscapeなんかは独特なサークルで進捗管理できるサービスです。他にも「Personal Goal」「Destination Management」なんかで検索するといろいろとツールが挙がってきます。

そもそも目標管理とは、とどのつまり目標を達成するためのタスク管理でもあります。このためGTD(Getting Things Done)という手法に代表される各種タスク管理ツールも、目標管理ツールと言えるでしょう。具体的に期日が決まっている目標であれば、一般的なスケジューラーを使うという手もあります。メモってあれば良いのであれば、人類が生み出した万能ツール「エクセル」やメモ帳もまた目標管理ツールになり得ます。

Ubuntuでのタスク管理と言えば第78回で小林さんがTasqueを紹介していますし、メモツールとしてのTomboyを第25回で吉田さんが紹介しています。同じく吉田さんが、第182回第185回においてCLI向けの強力なタスク管理ツールであるTaskwarriorも紹介してくれていますね。

それ以外にもPython-Gtkで作られたGetting Things GNOMEやタスク管理というよりはプロジェクト管理に近いGNOME Plannerなんてのもあります。プロプライエタリではあるもの、UbuntuソフトウェアセンターからはNitroというツールもインストールできますし、サーバー向けだとhordeといった「グループウェア」がタスク管理ツール機能も持っています。

ただどれも一長一短というか、機能が足りなかったり、多すぎたり、開発が止まっていたり、モバイルとの連携がなかったりと、なかなかうまく合うものがありません。特に日々強制的に目にするための機能が欲しいところです。

そこで今回は、改めてTaskwarriorを活用する方向で考えてみます。

コマンドライン向けタスク管理ツール:Taskwarrior

「コマンドライン向け」とか、いきなりWebブラウザーでもスマートフォンでもなくなりましたが、大丈夫です安心してください。後でなんとかします。なんとかしてくれる方を紹介します。

Taskwarriorについては先ほども述べたように第182回第185回を参照してください。当時からだいぶ機能追加や改善が行われていますが、基本的な概念については変わっていません。コマンドラインですべて操作できるタスク管理ツールであること、データはテキストとして保存されるのでいざとなれば直接データファイルを覗くこともできること、ぐらいを把握していれば充分です。

さて、Taskwarriorそのものはデータをローカルディスクに保存します。このため複数のマシン間でタスクを同期したい場合は、第185回での冒頭でも紹介しているようにDropboxや(今は亡きストレージサービスのほうの)Ubuntu Oneといった外部サービスを使う必要がありました。この場合、ちゃんと同期できるかどうか、どの版が最新版として扱われるかは外部サービスに依存し、Taskwarrior側からは管理できないという難点があります。さらにサービスによっては、公序良俗に反するタスクを追加したらアカウントが凍結されるリスクも存在します。よって人間の欲望の限界に日々挑戦している戦士の方にはこの方法は厳しいかもしれません。

そこで出てくるのがTaskwarrior専用のサーバーであるTaskserverです。Taskwarriorのシンプルなデータ構造はそのままに、公開鍵認証を使ったセキュアなデータ通信や、マルチグループ・マルチユーザー対応といった基本的な要素は押さえたタスク管理サーバーとなっています。Taskserver対応のウェブサービスやAndroidアプリも出て来ていますので、⁠Webブラウザーやスマートフォン」でタスク管理できる、というわけです。

Taskwarriorをインストールする

実は今回の目的のためにTaskwarriorをインストールしなくてもかまいません。ただTaskserverのテストにはクライアントがあったほうが便利なので、手順だけ紹介しておきます。特にいらない場合は、次の「Taskserverをインストールする」まで読み飛ばしても問題ありません。

さて、Taskwarriorそのものは「task」というパッケージ名でリポジトリに存在するため、aptコマンドでインストール可能です。ただ、ここでインストールできるバージョンはUbuntu 14.04 LTSだと2.2、14.10以降が2.3になっています[2]⁠。

Taskserverの現行バージョンである1.0はTaskwarrior 2.3と同時期にリリースされた関係上、Taskserverと一緒に使うなら2.3以降が欲しいところです。そこで、せっかくなので2015年の1月1日にリリースされたばかりの2.4をビルドしてインストールする方法を紹介しておきましょう[3]⁠。

$ mkdir task && cd $_
$ curl -LO http://taskwarrior.org/download/task-2.4.0.tar.gz
$ tar xvf task-2.4.0.tar.gz
$ cd task-2.4.0
$ sudo apt install build-essential cmake uuid-dev libgnutls-dev
$ cmake -DCMAKE_BUILD_TYPE=release .
$ make
$ sudo make install

これだけです。インストールできたらtask addやtask listが正しく動いているかどうか確認しましょう。とりあえず動作確認のために、適当なタスクを一気呵成にうぉりゃーっと追加しておきます。

$ task add スクフェスをはじめる project:目標
$ task add スクフェス用のスマホを用意する
$ task add スクフェスをインストールする
$ task add 今年中にランクを100まであげる
$ task 1 modify depends:2-4 due:eoy
$ task 2-4 modify project:目標

$ task add Recipeをコンスタントに執筆する project:目標
$ task add 毎月Recipeを執筆する due:eom recur:monthly until:eoy
$ task add RecipeSnappyネタを執筆する
$ task add RecipeMakeネタを執筆する
$ task add RecipeClickネタを執筆する
$ task 5 modify depends:6-9 due:eoy
$ task 6-9 modify project:目標

$ task add 挨拶はチキン亭 +標語 until:eoy
$ task add なるべく妖怪のせいにしない +標語 until:eoy
$ task add よく寝て、よく眠る +標語 until:eoy
$ task add 悩んだら牛乳に相談! +標語 until:eoy
$ task add なせば大抵なんとかならないかもしれない +標語 until:eoy

何をどう設定しているかはなんとなくわかってもらえるのではないでしょうか。ちなみに今年の目標は「目標」というプロジェクトにすべて親タスクとして追加し、その目標を実現するために必要なタスクに依存させるようにしています。子タスクをすべて完了にできれば、目標達成というわけです。

ちなみにTaskwarrior 2.4では、ISO-8601形式の日時表記やeoy(End of this year)のような単語も対応しています。これにより特定の時刻に始まるタスクなども設定できるようになりました。

$ task add 健康診断@部室 scheduled:2015-04-10T11:00 due:scheduled+1hour

Taskserverをインストールする

次に適当なUbuntuサーバーにTaskserverをビルドしてインストールします。このあとスマートフォンからもアクセスするので、そちらと通信可能なサーバーを用意してください。ちなみにクライアント側(Taskwarriorなど)は常時サーバーと通信するわけではありません。Gitのように必要なタイミングでユーザーの操作によって同期します。常時起動しているマシンにTaskserverをインストールしたほうが便利ではあるものの、それが必須というわけではありません。

$ mkdir taskd && cd $_
$ curl -LO http://taskwarrior.org/download/taskd-1.0.0.tar.gz
$ tar xvf taskd-1.0.0.tar.gz
$ cd taskd-1.0.0
$ sudo apt install build-essential cmake uuid-dev libgnutls-dev gnutls-bin
$ cmake -DCMAKE_BUILD_TYPE=release .
$ make
$ sudo make install

既定の通信ポートとして53589を利用します。ファイヤーウォールなどでこのポートを許可しておいてください。

Taskserver用にtaskdユーザーを作成し、デーモンはこのユーザーで実行するようにしましょう。

$ sudo adduser --system --no-create-home --disabled-login taskd

さらにTaskserver用のディレクトリを作成し、taskdコマンドで初期化しておきます。

$ sudo mkdir /var/taskd
$ sudo chown taskd /var/taskd
$ sudo -u taskd taskd init --data /var/taskd

次にTaskserverの証明書と鍵を作成します。taskdのソースコードの中には、生成スクリプトがあるのでこれを使うと良いでしょう。もちろん、公式な証明書を使ってもかまいません。生成スクリプトの一部であるgenerate.serverには、Taskwarriorのサイトの設定が書き込まれていますので、これを自分のサーバーのそれに変更します。

$ cd pki
$ editor generate.server
organization = (組織名)
cn = (一般名)
dns_name = "(サーバーのドメイン名)"
ip_address = "(サーバーのIPアドレス)"
$ ./generate
$ sudo install -o taskd -m 600 *.pem /var/taskd/
$ sudo -u taskd taskd config --data /var/taskd --force client.cert /var/taskd/client.cert.pem
$ sudo -u taskd taskd config --data /var/taskd --force client.key /var/taskd/client.key.pem
$ sudo -u taskd taskd config --data /var/taskd --force server.cert /var/taskd/server.cert.pem
$ sudo -u taskd taskd config --data /var/taskd --force server.key /var/taskd/server.key.pem
$ sudo -u taskd taskd config --data /var/taskd --force server.crl /var/taskd/server.crl.pem
$ sudo -u taskd taskd config --data /var/taskd --force ca.cert /var/taskd/ca.cert.pem
$ sudo -u taskd taskd config --data /var/taskd --force server 0.0.0.0:53589
$ sudo -u taskd taskd config --data /var/taskd --force client.allow '^task [2-9],Mirakel [2-9]'

最後の2つはサーバーのlistenアドレスとポート、接続可能なクライアントの名前とバージョンを指定しています。ちなみに逐一taskdコマンドを実行せずに、直接/var/taskd/configを編集してもかまいませんし、⁠--data」オプションが面倒なら環境変数「$TASKDDATA⁠⁠ にデータディレクトリを設定すれば省略可能です。

Taskserverには最初からtaskdctlという起動スクリプトが同梱されています。環境変数$TASKDDATAを設定のうえで、⁠taskdctl start」を実行するとTaskserverを起動してくれるのです。しかしながら今回はサーバー起動時に自動的にTaskserverを起動させたいのでUpstartのスクリプトを書くことにします[4]⁠。/etc/init/taskd.confを次のように編集してください。

description "Taskserver"
author  "Author Name <author@example.com>"

start on runlevel [2345]
stop on runlevel [!2345]

setuid taskd
respawn

exec taskd server --data /var/taskd

あとは実際にTaskserverを起動するだけです。

$ sudo start taskd
$ ps -fe | grep taskd
taskd    11130     1 60 18:33 ?        00:00:06 taskd server --data /var/taskd
ubuntu   11145   916  0 18:33 pts/0    00:00:00 grep --color=auto taskd
$ ss -ltn
State      Recv-Q Send-Q  Local Address:Port    Peer Address:Port
LISTEN     0      10                  *:53589              *:*
LISTEN     0      128                 *:22                 *:*
LISTEN     0      128                :::22                :::*

最初はpsコマンドやssコマンドで、期待通りTaskserverが起動できていることを確認してください。起動ログは初期設定だと/tmp/taskd.logとなります。あとは指定したポートが外部に公開されていれば、サーバーとしての共通の準備は完了です。

Taskserverにアカウントを作成する

Taskserverが無事に起動するようになりました。次にクライアントから接続できるようアカウントとその他もろもろを作成します。具体的には以下の作業を行います。

  • Taskserverへの組織とユーザーの追加
  • クライアント用の証明書と鍵を作成
  • クライアント側の接続先設定

まずはTaskserverに組織(oranization)とユーザーを作成します。組織名もユーザー名も任意の名前で問題ありません。ユーザー作成時にユニークなユーザーIDが発行されますので、それも記録しておいてください。このユーザーIDは複数のクライアントで共有することになります。ユーザーIDと表現していますが、サーバー側から見た場合、ユーザーの簡易パスワードみたいな存在ですので取り扱いには注意してください。

$ sudo -u taskd taskd add --data /var/taskd org Public
Created organization 'Public'
$ sudo -u taskd taskd add --data /var/taskd user 'Public' 'Mitsuya Shibata'
New user key: 3971315c-36ee-471f-b1d6-c0396fdcf635
Created user 'Mitsuya Shibata' for organization 'Public'
$ sudo restart taskd

次にサーバーの証明書と同様にTaskserverのソースコードのpkiディレクトリで、クライアント証明書を作成します。

$ ./generate.client shibata

「shibata」の部分はファイル名の使われるだけなので、任意の値に変更しても大丈夫です。作成された「shibata.key.pem」「shibata.cert.pem⁠⁠、さらにサーバー証明書作成時に作った「ca.cert.pem」をクライアント側の「.task」ディレクトリにコピーします。

あとはこの証明書とTaskserverのアドレスをTaskwarriorに設定するだけです。taskd.serverのアドレスとポート番号は各自の値に、taskd.credentialsはTaskserverにアカウントを作成した時のIDに変更してください[5]⁠。

$ chown 400 ~/.task/*.pem
$ echo >> ~/.taskrc <<EOF
taskd.certificate=/home/ubuntu/.task/shibata.cert.pem
taskd.key=/home/ubuntu/.task/shibata.key.pem
taskd.ca=/home/ubuntu/.task/ca.cert.pem
taskd.server=(Taskserverのアドレス):53589
taskd.credentials=Public/Mitsuya Shibata/3971315c-36ee-471f-b1d6-c0396fdcf635
EOF

ここまででクライアント側の設定は完了です。Taskserverと同期してみましょう。初回同期時は一度すべてのデータをサーバーに送信する必要があるため、initオプション付きで実行します。

$ task sync init
Please confirm that you wish to upload all your pending tasks to the Taskserver (yes/no) yes
Syncing with Taskserverのアドレス):53589

Sync successful.  16 changes uploaded.

これで同期完了です。もし認証に失敗する場合は、Taskserverの/tmp/taskd.logを確認してください。うまくいった場合も念の為、Taskserver側にデータが保存されているか確認しておきましょう。

$ sudo cat /var/taskd/orgs/Public/users/3971315c-36ee-471f-b1d6-c0396fdcf635/tx.data

今後はクライアント側でタスクを変更したあとにタスクを確認すると、同期が必要なことが通知されます。差分アップデートとしてinitオプションなしの「task sync」コマンドを実行してください。

$ task add 客先打ち合わせ@大赦 due:28th recur:monthly until:eoy
$ task list
(中略)
There are local changes.  Sync required.
$ task sync

Android向けタスク管理ツール:Mirakel

MirakelはTaskserverに対応したタスク管理アプリで、Google PlayからAndroid用パッケージをインストールできます。ちなみにアプリ内購入のパーミッションは寄付用のインターフェースがあるためです。

Taskwarriorと同様にクライアント証明書を作成します。アカウントは同じなので、ユーザーIDのほうは同じままです。作成した証明書類はただのテキストファイルなので、Mirakelの場合はそのまま設定ファイルに埋め込みます。

まず以下のようなファイルを作成してください。名前はmirakel.confとします。各項目はそれぞれの値に変更してください。

username: Mitsuya Shibata
org: Public
user key: 3971315c-36ee-471f-b1d6-c0396fdcf635
server: Taskserverのアドレス):53589

次に証明書類をこのファイルに追記していきます。

$ echo "client.cert:" >> mirakel.conf
$ cat shibata.cert.pem >> mirakel.conf
$ echo "Client.key:" >> mirakel.conf
$ cat shibata.key.pem >> mirakel.conf
$ echo "ca.cert:" >> mirakel.conf
$ cat ca.cert.pem >> mirakel.conf

この設定ファイルをスマートフォンに移動しておいてください。Mirakelをインストールしたら起動して、Settings→Sync→+ボタン→Taskwarrior syncを選択します。

図1 MirakelのTaskwarrior設定画面
図1 MirakelのTaskwarrior設定画面

上記画面で「Select config file」を押して、先程移動したmirakel.confファイルを選択してください。アプリのトップに戻るとSettingsが表示されていたところに「Sync Now」が追加されていますので、それを押すと同期します。

図2 Androidのバージョンによってこのメニューの表示方法は異なる
図2 Androidのバージョンによってこのメニューの表示方法は異なる
図3 同期が完了したら、タスクが表示される
図3 同期が完了したら、タスクが表示される

同期はすぐに完了するはずです。もしうまく同期できない場合はエラーメッセージやTaskserever側のログを確認してください。特にTaskserverのclient.allowで「Mirakel」を許可していないと、接続できません。

あとはMirakelでタスクを追加して同期したり、それが別クライアントでも同期されることを確認すると良いでしょう。

天は自らタスクる者を助く

今回は、以前取り上げたTaskwarriorをマルチクライアント・マルチデバイスで活用する方法をご紹介しました。ちなみに自前でTaskserverを立てたくない、Webブラウザーからも操作したいと言う方にはInthe.AMという、Taskserverを内蔵しているDjangoで開発されたWebサービスも存在します。GitHubでコードが公開されているAGPLv3なライセンスのソフトウェアですので、自前で同様のサービスを立ち上げることも可能でしょう。

このようにできるだけタスク管理部分を簡単にしておけば、日常のルーチンワークが苦手なものぐさな人でも「目標を忘れない」ことぐらいなら実現できるんじゃないかと睨んでいます。ただしこれはGTDで言うところの処理や整理、見直しの手間を減らしたにすぎません。収集や実行については、自分でがんばらなくてはならないということだけは覚えておきましょう。

さらに大きな問題は、今年の元旦がとっくに過ぎているということです。残念ながら2015年の計をたてるには手遅れです。というわけで今年の目標は「2016年の元旦に目標をたてる」にしたいと思います。

$ task delete project:目標
$ task add 2016年の元旦に目標をたてる project:目標 scheduled:soy due:soy
$ task sync

おすすめ記事

記事・ニュース一覧