Alfred之workflow入門

JavaDog發表於2019-01-28

前言

小帽子alfred可以說是macOS上最佳的效率軟體了,而其中最強大的功能就屬alfred 2.0推出的Workflow特性了。就像我們工程師遇到重複性工作總是想寫指令碼或者程式來解放自己一樣,workflow功能允許你將日常重複性的工作通過使用指令碼語言(bash、zsh、php、ruby、python、perl、as、js)封裝起來,通過alfred作為統一入口進行使用。

因為alfred的受眾之廣,所以寫workflow被設計的門檻非常低,低到了官方都沒有寫文字教程,只在alfred內嵌了幾個demo給使用者自己學習。本文將使用一個示例來詳細說明workflow的開發流程。

使用者介面

安裝好alfred以後,使用預設快捷鍵 option + space 開啟alfred入口:

image.png

Command + , 開啟設定頁面:

image.png

開啟workflow選項卡:

image.png

點選左下角 + 號,可以新建workflow或者檢視一些官方的模板以及上面提到的官方的demo示例。

image.png

好了,基本操作介面就介紹那麼多,下面就開始我們的workflow之旅吧!

準備工作

由於workflow功能是付費的,所以需要提前購買。具體型別、金額可以參考官網購買地址:官網購買地址。開發語言我們選擇的是python2.7,一個是語言簡單,另外個是python有很多現成的workflow的庫,這些庫幫助我們遮蔽了和alfred的互動,讓我們專注業務資料的開發,例如:,github.com/deanishe/al…。範例裡我們即使用這個庫來進行開發。

開發流程

基礎概念

在開發之前我們需要理解workflow的幾個基本概念

  • Triggers
  • Inputs
  • Actions
  • Outputs
Triggers

Triggers是觸發器,不是必須內容,一般繫結某個快捷鍵來觸發指定的workflow。

Inputs

inputs是我們使用workflow的核心,inputs主要是控制你在alfred視窗輸入快捷鍵和關鍵字以後展示的內容,以最常用的有道翻譯為例:

image.png

可以看出inputs就是我們需要重點開發的東西,因為Inputs可以使關鍵字通過指令碼轉化為許多列的結果展示給我們,而這個正是我們需要的。實際上workflow展示出的結果在指令碼中的表現形式就是一個xml檔案,示例如下:

image.png

對應的xml:

<?xml version="1.0"?>
<items>
    <item uid="1" arg="引數1" valid="yes">
        <title>這個是個title</title>
        <subtitle>這個是個subtitle</subtitle>
        <icon>icon.png</icon>
    </item>
    <item uid="2" arg="引數2" valid="yes">
        <title>這個是個title222</title>
        <subtitle>這個是個subtitle222</subtitle>
        <icon>icon.png</icon>
    </item>
</items>
複製程式碼

可以看到每行展示的內容被定義為一個item,每個item有一個uid,arg 。uid是每個item的唯一編號,不常用。arg指的是當在這個item上觸發事件的時候(例如點選enter),傳遞給下一個指令碼或者說Actions指令碼的入參。

實際上我們編寫workflow的核心就是為了生成這個xml

Actions

actions對應選中項(item)選中點選以後的操作,例如根據選項開啟一個網頁等。

Outputs

Outputs一般用於顯示操作的結果,提示操作成功與否,以Post Notification(提示操作狀態)、Copy to Clipboard(copy到剪下板)較為常見。

還是以有道翻譯為例,以上四個概念如圖:

image.png

看圖可以總結出workflow的基本工作方式:
image.png
需要注意的是,

從圖上可以看到整個工作流程中,最初的輸入是使用者輸入的關鍵字,但是隨著流轉上一個指令碼的輸出是下一個指令碼的輸入

好了到此我們workflow的基本概念就介紹完畢,現在讓我們直接進入workflow的開發工作吧。

指令碼開發

個人總結出來的一個workflow的開發流程如下:

  1. 明確需求
  2. 畫思路圖(熟練以後,直接和步驟3合併)
  3. 寫指令碼,除錯

下面我們就根據以上三個步驟來示範一個workflow的開發。

明確需求

例如我想開發一個豆瓣搜尋圖書的workflow,當我輸入書名字的時候,可以在展示出所有關聯的書的列表,然後每條記錄展示書的名稱,書的作者以及出版年份。我們在腦子裡腦補了一下,大概做出來的效果如下:

image.png

畫思路圖

image.png

寫指令碼

因為我們使用的python的第三方庫,而這個第三方庫其實作者已經寫了非常詳細的使用方法以及附了2個範例,可以看原文:www.deanishe.net/alfred-work…(強烈建議有餘力的同學讀原版教程),這裡我就簡單的結合我們的需求加工(翻譯)下:

1、建立一個workflow

首先,建立一個新的,空白的workflow,如圖:

image.png

2、簡單描述下你的workflow

點選Blank Workflow以後會跳出workflow的基本配置視窗,圖如下,需要注意的是bundle Id的填寫,該欄位需要在你所有的workflow理保持唯一(類的全路徑名)。可以將一個圖片拖動到workflow上來改變workflow的外觀,填寫完畢點選create即可儲存。

image.png

3、新增Script Filter

雙擊新建立的workflow,在空白處右鍵建立一個Script Filter,通過上面的基礎概念說明我們可以瞭解,Script Filter是Inputs的一種,而Inputs的作用是接收使用者輸入(可選),然後根據使用者輸入通過指令碼過濾展示資料。

image.png

在建立Script Filter的時候,我們需要填寫一些基本資訊,如圖。keyword表示該workflow的觸發的快捷鍵,參考基礎概念圖中的yd 和 test。因為我們搜尋豆瓣圖書的時候是需要輸入書名字的,所以選擇 Argument Required,這個其實就是強制要求必須輸入引數才會執行指令碼,當然有的workflow也是不需要入參的。

image.png

image.png

4、編寫除錯你的python指令碼

建立完Script Filter以後在workflow上右鍵,open in finder,開啟workflow的本地資料夾:

image.png

開啟以後一個空白的workflow應該是如下的:

image.png

可以看到只有一個圖示和一個info.plist,可以開啟info.plist檢視,裡面是該workflow的所有配置資訊,這裡就不說了。

為了正常使用該python的第三方庫,我們需要在github上下載該庫:github.com/deanishe/al…,並且複製其中的workflow資料夾到你本地的workflow資料夾,複製好以後你本地的workflow資料夾列表應該如下:

image.png

同時我們需要在該資料夾下建立我們的主要指令碼檔案,douban.py(在script filter中配置的),最終全部建立好以後如下:

image.png

最後我們只需要編寫douban.py的程式碼即可。ps:比較方便一點的是先在編輯器中建立檔案,然後編輯除錯好程式碼直接複製過去即可。

限於篇幅就不一一說明每行程式碼方式了,如下:

# -*- coding: utf-8 -*-

import sys

import requests

from workflow import Workflow, ICON_WEB


def get_recent_posts(query):
    # 豆瓣開放api
    url = 'https://api.douban.com/v2/book/search'
    # 查詢引數
    query_string = dict(q=query)
    headers = {
        'cache-control': "no-cache",
    }
    r = requests.request("GET", url, headers=headers, params=query_string)
    # 如果有異常 丟擲
    r.raise_for_status()
    # 獲取json資料 範例參見  https://api.douban.com/v2/book/search?q=三體
    result = r.json()
    # 獲取搜尋的書籍資料
    posts = result['books']
    return posts


def main(wf):
    # 從alfred獲取query
    if len(wf.args):
        query = wf.args[0]
    else:
        query = None
    # 根據query獲取資料
    posts = get_recent_posts(query)

    # 封裝xml,即展示的頁面需要什麼資料,拼裝資料
    for post in posts:
        title = post['title'] + "  " + post['author'][0]
        subtitle = post['subtitle'] + "  " + post['publisher'] + "  " + post['pubdate']
        wf.add_item(title=title, subtitle=subtitle, arg=post['alt'], valid=True, icon=ICON_WEB)
    # 把資料傳送給alfred展示
    wf.send_feedback()


if __name__ == u"__main__":
    # 新建workflow物件
    wf = Workflow()
    # 執行main方法
    sys.exit(wf.run(main))

複製程式碼

可以看到,使用第三方庫開發workflow的流程如下:

image.png

其中只有2,和3的封裝過程需要我們編寫程式碼,第三方庫完全遮蔽了我們和alfred的互動,可以讓我們更專注在資料的開發上。

以上程式碼編寫完,測試效果如下:

image.png

5、新增workflow的actions

我們搜尋了書籍,如果看到感興趣的書,肯定想著說開啟一些書的主頁看下,那麼難道還需要跑到豆瓣上再去開啟?當然是不需要的。所以我們需要一個【選中一個選項直接enter或者shift開啟這本書對應的豆瓣主頁】的功能,那麼actions就是做這個動作的。在script filter上右鍵 新增一個actions:

image.png

image.png

需要注意的是這裡的query並非是使用者一開始輸入的query,因為觸發這個動作是點選script filter中的一個item觸發的,所以這裡的query指的是【基礎概念】章節介紹的xml格式裡面的每個item對應的arg,參照我們python的程式碼裡表示的是每本書的主頁的連結地址!

wf.add_item(title=title, subtitle=subtitle, arg=post['alt'], valid=True, icon=ICON_WEB)
複製程式碼

image.png

當然,如果你想更改點選的快捷鍵,可以單擊script filter 和actions的連結:

image.png

image.png

好了到此為止,我們就大功告成了,這時候點選alfred搜尋出來的資料,可以直接使用chrome開啟書的主頁了,當然既然用到了第三方庫,第三方庫還是有很多高階功能的,比如快取,主要目的是放置被api伺服器ban掉,可以把搜尋的資料快取在本地,具體的api可以參考該第三方庫的文件:www.deanishe.net/alfred-work…

其他

  1. 其實我們平時需要些workflow的地方很少,更多的用的是配置快捷鍵開啟指定網址的功能,可以讓我們快速的在內網各個系統中來回穿梭。
  2. 如果需要寫workflow的話也沒必要親自寫。有很多網站維護了很多的常用的workflow,比如:alfredworkflow.com/ 裡就有各種常用的。
  3. workflow當然不止文章中表述的功能那麼簡單,還可以開發更復雜更靈活的功能,需要大家自己研究了。
  4. workflow最好的學習方法不是自己琢磨研究,而是拿功能類似的過來改吧改吧,改的次數多了,很快就熟悉了。
  5. 示例見附件,下載後雙擊即可匯入。
  6. 有收穫,點個讚唄!

參考文章

www.zhihu.com/question/22…

alfredworkflow.com/

github.com/deanishe/al…

www.deanishe.net/alfred-work…

myg0u.com/python/2015…

computers.tutsplus.com/tutorials/a…

developers.douban.com/wiki/?title…

碼字不易,如有建議請掃碼Alfred之workflow入門


相關文章