LoginSignup
0

More than 1 year has passed since last update.

Alfred Workflows + Rust で Qiita の記事を検索する

Last updated at Posted at 2021-08-31

Mac の人気なランチャーアプリ Alfred のワークフローを Rust を使って作成する方法についてご紹介します。

今回は Qiita の記事を検索するワークフローを作成します。以下の記事を参考にさせていただきました。

alfred-qiita-search-4.gif

プログラムを作成する

alfred というクレートを使用します。これは Alfred が読み込める形の JSON を簡単に作成できるクレートです。キーワードをコマンドライン引数で受け取って、Alfred が読み込める形の JSON を標準出力に出力するコードを作成します。

use chrono::{DateTime, FixedOffset};
use serde::Deserialize;

#[derive(Deserialize, Debug)]
struct QiitaItem {
    title: String,
    user: QiitaUser,
    url: String,
    created_at: String,
}

#[derive(Deserialize, Debug)]
struct QiitaUser {
    id: String,
}

// Qiita から返ってきた日時(文字列)を日本時間(文字列)にフォーマット
fn format_date(date_string: &str) -> String {
    DateTime::parse_from_rfc3339(date_string)
        .ok()
        .map(|date| {
            date.with_timezone(&FixedOffset::east(9 * 3600)) // +9時間
                .format("%Y/%m/%d %H:%M")
                .to_string()
        })
        .unwrap_or("".to_owned())
}

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

    let search_word = args.join(" ");
    let access_token = match std::env::var("QIITA_ACCESS_TOKEN") {
        Ok(x) => x,
        _ => return,
    };

    // Qiita の検索 API を実行
    let qiita_items: Vec<QiitaItem> = ureq::get(&format!(
        "https://qiita.com/api/v2/items?query=body:{}",
        search_word
    ))
    .set("Authorization", &format!("Bearer {}", access_token))
    .call()
    .ok()
    .and_then(|res| res.into_json().ok())
    .unwrap_or(vec![]);

    // 取得したデータを Alfred が読み込めるように変換
    let alfred_items: Vec<_> = qiita_items
        .into_iter()
        .map(|qiita_item| {
            alfred::ItemBuilder::new(qiita_item.title)
                .subtitle(format!(
                    "@{} {}",
                    qiita_item.user.id,
                    format_date(&qiita_item.created_at)
                ))
                .arg(qiita_item.url)
                .icon_path("./icon.png") // ワークフローに設定されているアイコンを使用する
                .into_item()
        })
        .collect();

    // JSON データを標準出力へ出力
    alfred::json::write_items(std::io::stdout(), &alfred_items).ok();
}
  • 軽量な HTTP クライアント ureq を使用しています。
  • ワークフローには環境変数を設定することができます。アクセストークンは環境変数から受け取るようにしています。
[package]
name = "alfred-qiita-search"
version = "0.1.0"
edition = "2018"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
alfred = "4.0.2"
ureq = { version = "2.1.1", features = ["json"] }
serde = { version = "1.0.126", features = ["derive"] }
chrono = "0.4"

Alfred でワークフローを作成する

空ワークフローを新規作成します。

スクリーンショット 2021-08-27 18.09.13.png

ワークフローの情報を記述します(ここでアイコンも設定しておきます)。

スクリーンショット 2021-08-27 18.10.09.png

ワークフローに Inputs > Script Filter を追加します。

スクリーンショット 2021-08-27 18.10.31.png

キーワードなどと一緒に以下のスクリプトを入力します。

スクリーンショット 2021-08-27 18.11.19.png

query=$1

./alfred-qiita-search $query

ワークフローに Actions > Open URL を追加します(何も設定せずそのまま保存します)。

スクリーンショット 2021-08-27 18.11.55.png

Script FilterOpen URL を接続します。

スクリーンショット 2021-08-27 18.12.14.png

環境変数を設定します(右上の [Χ] のようなアイコンから設定できます)。

スクリーンショット 2021-08-27 18.14.33.png

バイナリを配置する

リリースビルドしてバイナリをワークフローのディレクトリ下に配置します。

$ cargo build --release
$ cp ./target/release/alfred-qiita-search ~/Library/Application\ Support/Alfred/Alfred.alfredpreferences/workflows/user.workflow.{上で作成したワークフローのUUID}/

※ワークフローのディレクトリは以下からターミナルで開くことができます。
スクリーンショット 2021-08-27 18.15.12.png

以上でワークフローの作成は完了です。qiita のプレフィックスの後にキーワードを入力するとその内容で検索をしてくれます。

alfred-qiita-search-4.gif

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0