Things 3 for MacをJXA (JavaScript for Automation) で操作するための詳細なメモ

大体のことは用語辞典に載ってるんですが、英語で書かれていることを差し引いても読みにくいんですよね。
今回これを書くために用語辞典を読みまくって、ようやく用語辞典の読み方がわかりました。

--

AppleScriptの知識を持っていない人が読んでわかるように書いたつもりです。

Things3内部の階層構造はこのようになっています。

複雑怪奇なOmniFocusのものと比較すると極めて明快な構造です。
順に見ていきます。

スポンサーリンク

Application

▼まずはApplicationオブジェクトを変数に入れるところから

var app = Application("Things3");

以下、このappという変数を説明に使用します。

Applicationに含まれているエレメント

  • windows
  • lists
  • toDos
  • projects
  • areas
  • tags
  • selectedToDos

エレメントとは同一クラスのオブジェクトからなる配列のことで、クラス名の複数形で表されます。
エレメントを取得するには、

app.windows();

のように()を付けてメソッドの形にして、.で繋げます。

Applicationのプロパティ

name

  • text, read only

frontmost

  • boolean, read only
  • アプリケーションが最前面にあるかどうか

version

  • text, read only
     

プロパティを取得するには、

app.name();

のようにプロパティ名に()を付けてメソッドの形にして、.で繋げます。

メソッド等

// 起動
app.activate();
// 終了
app.quit();
// ゴミ箱を空にする
app.emptyTrash();
// 「今すぐログ」を実行
app.logCompletedNow();

windows

開かれているウィンドウ (Windowオブジェクト) の配列です。

app.windows();

windowsの先頭には"Quick Entry"というよくわからないオブジェクトが入っていますので、実際のウィンドウは2つ目以降になります。

app.windows().slice(1);

windowsを含むクラス

  • Application

Windowのプロパティ

name

  • text, read only
  • ウィンドウ名

bounds

  • rectangle
  • ウィンドウの位置と大きさの情報

    x, yは、ディスプレイ左上を基準としたウィンドウ左上の角の座標です。
var position = app.windows()[1].bounds();
// ウィンドウの高さを取得する
var height = position["height"];
// ウィンドウの位置と大きさを変更する
app.windows()[1].bounds = {"x":100, "y":230, "width":850, "height":600};

 

リードオンリーではないプロパティの値を設定するには、このように=で代入します。
プロパティの値をgetする時は.bounds()で、setする時はカッコなしの.boundsです。

minimized

  • boolean
  • ウィンドウが最小化されているかどうか
// ウィンドウの最小化を解除
app.windows()[1].minimized = false;
app.activate();

visible

  • boolean
  • ウィンドウが表示されているかどうか
  • minimizedとの違いはあるが詳細不明

zoomed

  • boolean
  • ウィンドウが拡大表示されているかどうか
// ウィンドウを拡大する
app.windows()[1].zoomed = true;

メソッド等

// ウィンドウを閉じる
app.windows()[1].close();

lists

7つのタスクリスト (Listオブジェクト) からなる配列です。
↓ この7つのリスト

// 受信
app.lists.byName("受信");
// 今日
app.lists.byName("今日");
// 明日以降
app.lists.byName("明日以降");
// いつでも
app.lists.byName("いつでも");
// いつか
app.lists.byName("いつか");
// ログブック
app.lists.byName("ログブック");
// ゴミ箱
app.lists.byName("ゴミ箱");

listsを含むクラス

  • Application

Listに含まれているエレメント

toDos

▼「受信」リストに含まれているタスクの配列

var list = app.lists.byName("受信");
var tasks = list.toDos();

Listのプロパティ

省略

メソッド等

▼明日以降のタブにフォーカスを移動する

app.lists.byName("明日以降").show();

toDos

個々のタスク (ToDoオブジェクト) の配列です。

toDosを含むクラス

  • Application
  • List
  • Project
  • Area
  • Tag

ToDoに含まれているエレメント

  • tags
    ▼タスクに設定されているタグの配列
var task = app.lists.byName("受信").toDos()[0];
var tags = task.tags();

ToDoのプロパティ

id

  • text, read only
  • ユニークな識別子

name

  • text
  • タスク名

▼タスク名を変更する

var task = app.lists.byName("受信").toDos()[0];
task.name = "新しいタスク名";

creationDate

  • date
  • 作成日時

▼作成日時を変更する

var today = new Date();
var task = app.lists.byName("受信").toDos()[0];
task.creationDate = today;

dueDate

  • date
  • タスクの期限日

▼期限日を設定or変更する

var due_date = new Date(2017, 5, 1);
var task = app.lists.byName("受信").toDos()[0];
task.dueDate = due_date;

activationDate

  • date, read only
  • これは何でしょうね? 誰か教えて下さい。

completionDate

  • date
  • 実行日時

cancellationDate

  • date
  • キャンセルとしてマークした日時

status

  • 列挙型
  • "open", "completed", "canceled" のいずれか
    open : 通常の状態
    completed : 完了済み
    canceled : キャンセルとしてマークされている

▼タスクを完了にする

var task = app.lists.byName("受信").toDos()[0];
task.status = "completed";

tagNames

  • text
  • ,で区切られたタグ名のテキスト

▼タグ名を取得

▼タグを追加

var task = app.lists.byName("受信").toDos()[0];
var old_tags = task.tagNames();
task.tagNames = old_tags + "," + "追加タグ1,追加タグ2";

上のスクリーンショットの通り、old_tags変数には変なスペースが入ってしまっていますが、タグ名の先頭と末尾のスペースは無効となる仕様のためこれで問題なく設定できます。

▼タグを全て削除

var task = app.lists.byName("受信").toDos()[0];
task.tagNames = "";

notes

  • text
  • タスクのメモ

▼メモ欄に書き込む

var task = app.lists.byName("受信").toDos()[0];
task.notes = "メモ。\nメモメモ。";

project

  • Projectオブジェクト

▼タスクをプロジェクトに登録

var project = app.projects.byName("プロジェクト名");
var task = app.lists.byName("受信").toDos[0];
task.project = project;

area

  • Areaオブジェクト

▼タスクをエリアに登録

var area = app.areas.byName("エリア名");
var task = app.lists.byName("受信").toDos[0];
task.area = area;

メソッド等

▼タスクを新規作成する

var date = new Date(2017, 5, 1);
var new_task = app.ToDo({  // ToDoオブジェクトを作成
    name: "タスク名",  // オブジェクトリテラルでプロパティを設定
    dueDate: date
});
app.toDos.push(new_task);  // toDosエレメントにpushで追加

▼タスクを削除する

var task = app.lists.byName("受信").toDos()[0];
task.delete();

▼タスクの編集画面を呼び出す

var task = app.lists.byName("受信").toDos()[0];
task.edit();

▼タスクにフォーカスを移す

var task = app.lists.byName("受信").toDos()[0];
task.show();

▼タスクの「いつ」を設定する(なぜかプロパティではない)

var date = new Date(2017, 5, 1);
var task = app.lists.byName("受信").toDos()[0];
task.schedule({for: date});

projects

プロジェクト (Projectオブジェクト) の配列です。

projectsを含むクラス

  • Application

Projectをプロパティとして含むクラス

  • ToDo

Projectに含まれているエレメント

  • toDos
    ▼プロジェクトに含まれるタスクの配列
var project = app.projects.byName("プロジェクト名");
var tasks = project.toDos();

Projectのプロパティ

ProjectはToDoのサブクラスなのでそちらを参照。

メソッド等

▼プロジェクトを名前指定で取得

var project = app.projects.byName("プロジェクト名");
// 同一名のプロジェクトが複数ある場合は一番上にあるものを取得

▼プロジェクトが存在するかどうか確認

var project = app.projects.byName("プロジェクト名");
project.exists();  // -> true か false

▼プロジェクトを新規作成

var new_project = app.Project({  // Projectオブジェクトを作成
    name: "プロジェクト名",  // オブジェクトリテラルでプロパティを設定
});
app.projects.push(new_project);  // projectsエレメントにpushで追加

delete(), edit(), show() ,schedule() についてはToDoと同様。

areas

エリア(Areaオブジェクト)の配列です。

areasを含むクラス

  • Application

Areaをプロパティとして含むクラス

  • ToDo
  • Project
  • SelectedToDo

Areaに含まれているエレメント

  • toDos
    ▼エリアに含まれるタスクの配列
var area = app.areas.byName("エリア名");
var tasks = area.toDos();

  • tags
    ▼エリアに設定されているタグの配列
var area = app.areas.byName("エリア名");
var tags = area.tags();

Areaのプロパティ

id

  • text, read only
  • ユニークな識別子

name

  • text
  • エリア名

tagNames

  • text
  • 詳細はToDoのtagNamesを参照

メソッド等

▼エリアを名前指定で取得

var area = app.areas.byName("エリア名");
// 同一名のエリアが複数ある場合は一番上にあるものを取得

▼エリアが存在するかどうか確認

var area = app.areas.byName("エリア名");
area.exists();  // -> true か false

▼エリアを新規作成

var new_area = app.Area({  // Areaオブジェクトを作成
    name: "エリア名",  // オブジェクトリテラルでプロパティを設定
});
app.areas.push(new_area);  // areasエレメントにpushで追加

delete(), show() についてはToDoと同様。

tags

タグ(Tagオブジェクト)の配列です。

tagsを含むクラス

  • Application
  • ToDo
  • Project
  • Area
  • Tag
    ▼タグの子タグの配列
var parent_tag = app.tags()[0];
var child_tags = parent_tag.tags();

  • SelectedToDo

Tagをプロパティとして含むクラス

  • Tag
    • parentTag : タグの親タグ

Tagのプロパティ

id

  • text, read only
  • ユニークな識別子

name

  • text
  • タグ名

▼タグの名前を変更

var target_tag = app.tags.byName("タグ名");
target_tag.name = "新しいタグ名";

keyboardShortcut

  • text
  • タグを付け外しするショートカットキー

▼ショートカットキーを設定もしくは変更

var target_tag = app.tags.byName("タグ名");
target_tag.keyboardShortcut = "r";  // ctrl + r でタグの付け外し

parentTag

  • Tagオブジェクト
  • タグの親タグ

メソッド等

▼タグをタグ名で取得

app.tags.byName("タグ名");

▼タグを削除

var tag = app.tags.byName("タグ名");
tag.delete();

▼タグを新規作成

var new_tag = app.Tag({  // Tagオブジェクトを作成
    name: "タグ名",  // オブジェクトリテラルでプロパティを設定
});
app.tags.push(new_tag);  // tagsエレメントにpushで追加

selectedToDos

ThingsのUI上で選択されているタスク(SelectedToDosオブジェクト)の配列です。

selectedToDosを含むクラス

  • Application

SelectedToDoのプロパティ

SelectedToDoはToDoのサブクラスなのでそちらを参照。

メソッド等

ToDoを参照。

▼選択されているタスクを順に処理

var tasks = app.selectedToDos();
for (var i = 0; i < tasks.length; i++) {
    console.log(tasks[i].name());
}

JXAに関する参考

AppleScript JavaScript for Automation (JXA) - 鳶嶋工房
Mac : JavaScript for Automation (JXA) 例文辞典
Google先生も知らないJXAのプライベートメソッド - Qiita
JavaScript for OS X Automation by Example(英語)

スポンサーリンク
スポンサーリンク

コメントを残す

メールアドレスが公開されることはありません。