Alfred Workflow で unixtime を日付に変換するスクリプトをつくる

はじめに

周りの人が使っているのを見て良さそうだったので、最近メジャーバージョンが 4 から 5 に上がったのを機に alfred の有料版を買いました。

有料版の機能の一つに workflow というキー入力に対して何らかの内部処理と出力を対応させるというものがあります。例えば"aws s3"と入力したら web の s3 の URL にとべたり、"emoji cool"と入れたら cool っぽい絵文字を clipboard に出力することができます。 awesome な workflow をまとめているサイトにいろいろ載っています。

workflow はありものを使うだけでなく自作も可能なので、簡単なものを作成してみることにしました。

作成したもの

unixtime を日付に変換するものと、その逆変換を行うものを作成しました。

手順

  1. alfred の gui で入出力のブロックを置く
  2. スクリプトを記述する
  3. 作成したスクリプトをalfredから読み込めるよう設定する

1. alfred の gui で入出力のブロックを置く

こんな感じで入力に Script Filter、出力に Copy to Clipboard を置きます。 unixtime ⇨ 日時 とその逆変換で 2 つ Script Filter を置いています。出力はクリップボードへのコピーで共通なので1つです。

2. スクリプトを記述する

Script Filter で読み込む用のスクリプトを作成します。 今回は Rust で書いてますが Python とかでも書けるはず。

unixtime ⇨ 日時

use chrono::{DateTime, Local, TimeZone};
use std::io;

fn main() {
    let args: Vec<String> = std::env::args().skip(1).collect();

    let unixtime = args[0].parse::<i64>().unwrap();
    let dt: DateTime<Local> = Local.timestamp(unixtime, 0);

    let _ = alfred::json::write_items(
        io::stdout(),
        &[alfred::ItemBuilder::new(dt.to_string())
            .arg(dt.to_string())
            .subtitle("convert unixtime to datetime")
            //.icon_filetype("public.folder")
            .into_item()],
    );
}

日時 ⇨ datetime

use chrono::{DateTime, Local, TimeZone};
use std::io;

fn main() {
    let input_args: Vec<String> = std::env::args().skip(1).collect();

    let input_args_str: String = input_args.get(0).unwrap().to_string();
    let args: Vec<&str> = input_args_str.split_whitespace().collect();

    let yyyymmdd = args[0];
    let mut hms = "";
    if args.len() == 1 {
        //日時を指定しないケース
        hms = "00:00:00";
    } else {
        hms = args.get(1).unwrap();
    }

    let dt: DateTime<Local> = Local
        .datetime_from_str(&(yyyymmdd.to_string() + hms), "%Y%m%d %H:%M:%S")
        .unwrap();
    let timestamp: i64 = dt.timestamp();

    let _ = alfred::json::write_items(
        io::stdout(),
        &[alfred::ItemBuilder::new(timestamp.to_string())
            .arg(timestamp.to_string())
            .subtitle("convert datetime to unixtime")
            //.icon_filetype("public.folder")
            .into_item()],
    );
}

例外処理とか入れてないので invalid な入力に対しては出力が出ませんが、自分用なのでいいでしょう。

入力は普通に標準入力として受け取れますが、複数の引数を入力したい場合は注意が必要です。 alfred における引数の入力では複数の引数があってもそれを一つにまとめてしまうらしく、 例えば引数が 20200910 00:00:00 という場合、arg[0]に 20200910、arg[1]に 00:00:00 が入ってきて欲しいのですが、args[0]にすべての引数が入ってきます。そのため上記のコードでは args[0] の中をさらに parse するという処理を行なっています。

出力部分は alfred 特有の json 形式にする必要がありますが、 Rust だとcrate があるのでこれを利用して記述します。

3. 作成したスクリプトを alfred から読み込めるよう設定する

worlflow のフォルダを上記の処理で開き、Rustでコンパイル済みの実行ファイルをこのフォルダにコピーします。 次に、Script Filterの設定画面を開き、実行ファイルの名前をコピーしたもの(この例では u2d)に置き換えれば完了です。

メモ

alfred はまだ初心者であまり機能を使いこなせている気はしませんが、 このようなよくやるけど何ステップか処理が必要なことを簡易化できるので、何か面白い使い道ができたらなーと思います。

参考資料