Alfred 4: MacOS效率提升大杀器(下篇)

Author: 颖奇L’Amore

Blog: www.gem-love.com


MacOS高效使用文章合集:here

前言

前篇中我们介绍了Alfred的内置feature,这篇文章介绍Alfred的终极技能:Workflow

注意,未激活的Alfred不支持workflow功能,所以你需要先购买powerpack激活码

初识workflow

workflow是由用户开发的工作流程,只要你懂得任何一门编程语言基本上都可以来编写自己的workflow,可以通过以下几个渠道获取别人分享的workflow:

  1. https://www.alfredapp.com/workflows/
  2. http://www.packal.org/workflow-list
  3. https://github.com/zenorocha/alfred-workflows
  4. https://github.com/alfred-workflows/awesome-alfred-workflows
  5. https://github.com/ctwise/alfred-workflows
  6. https://pacmax.org/
  7. https://github.com/vitorgalvao/alfred-workflows/
  8. https://www.alfredforum.com/forum/3-share-your-workflows/

其中8是论坛,大家可以自由分享自己写的workflow;其他是精选workflow合集,上面第3个里有相应的效果图,可以先去点进去看一下workflow的使用效果,然后下载自己需要的workflow

Debug

有时候我们发现导入了别人的workflow,然后自己用不了,这时候就需要调试了
这里我以我自己的环境为例,实际操作一下debug and fix的流程

举例1:encode / decode

下载:https://github.com/willfarrell/alfred-encode-decode-workflow
这是它的使用效果:

但是我却用不了:

此时我们进入该workflow,点击右上角的🕷打开debug页面,可以发现错误原因是/bin/bash: php: command not found

那么我们双击encode和decode的script filter打开,发现它的代码实际上是直接用bash去执行了php

这可能是PATH中找不到php的路径,所以我们直接将其改为自己的php的绝对路径

改完之后就能用了:

举例2:DevDocs

下载:https://github.com/yannickglt/alfred-devdocs
这是它的使用效果:

同样我本地用不了:

报错显示找不到所使用的的编程语言,进入workflow双击打开,可以发现它使用的是/usr/bin/php而我们的php不在这个目录

首先考虑用软链接把php链接过来,但奈何/usr/bin目录在当前macos版本已经不可写了

这时候只能用bash去调用php了

首先我们先看一个run script,是不用传参的

使用的语言改成/bin/bash,同时代码改成:

/Applications/MxSrvs/bin/php/bin/php -r '$query = "nuke";require_once("scripts/conf.php");'

然后我们看node这个script filter,原本使用的/usr/bin/php时的代码如下:

$query = "{query}";
$documentation = 'node';
require_once("scripts/devdocs.php");


这个是要接收参数的,有点麻烦,我们先右键open in finder进入该workflow的目录

新建一个node.php,代码写成:

<?php
$query = $argv[1];
$documentation = 'node';
require_once("scripts/devdocs.php");

然后使用的语言改成/bin/bash,同时代码改成:

query="{query}"
/Applications/MxSrvs/bin/php/bin/php node.php $query

此时就解决了/usr/bin/php未安装的问题,尽管此时还不能用,debug显示报错为网页访问不了(但这不是我们workflow的问题了,是对方的文档请求不了了,node命令是直接去这个远程文档去搜索的):

Warning: file_get_contents(http://maxcdn-docs.devdocs.io/node/index.json): failed to open stream: php_network_getaddresses: getaddrinfo failed: nodename nor servname provided, or not known in /Users/amortang/Library/Application Support/Alfred/Alfred.alfredpreferences/workflows/user.workflow.9CE45714-7860-4A74-B002-78AA58F3BC8E/scripts/devdocs.php on line 73

同样的方法把其他的script filter给处理了,依然不能用,看debug的php报错信息:

Deprecated: Array and string offset access syntax with curly braces is deprecated in /Users/amortang/Library/Application Support/Alfred/Alfred.alfredpreferences/workflows/user.workflow.9CE45714-7860-4A74-B002-78AA58F3BC8E/scripts/vendor/rodneyrehm/plist/classes/CFPropertyList/CFBinaryPropertyList.php on line 787

Call Stack:
0.0002 395432 1. {main}() /Users/amortang/Library/Application Support/Alfred/Alfred.alfredpreferences/workflows/user.workflow.9CE45714-7860-4A74-B002-78AA58F3BC8E/cdocadd.php:0
0.0008 443448 2. require_once('/Users/amortang/Library/Application Support/Alfred/Alfred.alfredpreferences/workflows/user.workflow.9CE45714-7860-4A74-B002-78AA58F3BC8E/scripts/conf.php') /Users/amortang/Library/Application Support/Alfred/Alfred.alfredpreferences/workflows/user.workflow.9CE45714-7860-4A74-B002-78AA58F3BC8E/cdocadd.php:4
0.0017 549832 3. CFPropertyList\DevDocsConf->__construct() /Users/amortang/Library/Application Support/Alfred/Alfred.alfredpreferences/workflows/user.workflow.9CE45714-7860-4A74-B002-78AA58F3BC8E/scripts/conf.php:253
0.1059 550896 4. CFPropertyList\DevDocsConf->openPlist() /Users/amortang/Library/Application Support/Alfred/Alfred.alfredpreferences/workflows/user.workflow.9CE45714-7860-4A74-B002-78AA58F3BC8E/scripts/conf.php:40
0.1059 550896 5. spl_autoload_call() /Users/amortang/Library/Application Support/Alfred/Alfred.alfredpreferences/workflows/user.workflow.9CE45714-7860-4A74-B002-78AA58F3BC8E/scripts/conf.php:51
0.1059 550952 6. Composer\Autoload\ClassLoader->loadClass() /Users/amortang/Library/Application Support/Alfred/Alfred.alfredpreferences/workflows/user.workflow.9CE45714-7860-4A74-B002-78AA58F3BC8E/scripts/conf.php:51
0.1059 551208 7. Composer\Autoload\includeFile() /Users/amortang/Library/Application Support/Alfred/Alfred.alfredpreferences/workflows/user.workflow.9CE45714-7860-4A74-B002-78AA58F3BC8E/scripts/vendor/composer/ClassLoader.php:274
0.1063 625656 8. include('/Users/amortang/Library/Application Support/Alfred/Alfred.alfredpreferences/workflows/user.workflow.9CE45714-7860-4A74-B002-78AA58F3BC8E/scripts/vendor/rodneyrehm/plist/classes/CFPropertyList/CFPropertyList.php') /Users/amortang/Library/Application Support/Alfred/Alfred.alfredpreferences/workflows/user.workflow.9CE45714-7860-4A74-B002-78AA58F3BC8E/scripts/vendor/composer/ClassLoader.php:382


Deprecated: Array and string offset access syntax with curly braces is deprecated in /Users/amortang/Library/Application Support/Alfred/Alfred.alfredpreferences/workflows/user.workflow.9CE45714-7860-4A74-B002-78AA58F3BC8E/scripts/vendor/rodneyrehm/plist/classes/CFPropertyList/CFBinaryPropertyList.php on line 810

Call Stack:
0.0002 395432 1. {main}() /Users/amortang/Library/Application Support/Alfred/Alfred.alfredpreferences/workflows/user.workflow.9CE45714-7860-4A74-B002-78AA58F3BC8E/cdocadd.php:0
0.0008 443448 2. require_once('/Users/amortang/Library/Application Support/Alfred/Alfred.alfredpreferences/workflows/user.workflow.9CE45714-7860-4A74-B002-78AA58F3BC8E/scripts/conf.php') /Users/amortang/Library/Application Support/Alfred/Alfred.alfredpreferences/workflows/user.workflow.9CE45714-7860-4A74-B002-78AA58F3BC8E/cdocadd.php:4
0.0017 549832 3. CFPropertyList\DevDocsConf->__construct() /Users/amortang/Library/Application Support/Alfred/Alfred.alfredpreferences/workflows/user.workflow.9CE45714-7860-4A74-B002-78AA58F3BC8E/scripts/conf.php:253
0.1059 550896 4. CFPropertyList\DevDocsConf->openPlist() /Users/amortang/Library/Application Support/Alfred/Alfred.alfredpreferences/workflows/user.workflow.9CE45714-7860-4A74-B002-78AA58F3BC8E/scripts/conf.php:40
0.1059 550896 5. spl_autoload_call() /Users/amortang/Library/Application Support/Alfred/Alfred.alfredpreferences/workflows/user.workflow.9CE45714-7860-4A74-B002-78AA58F3BC8E/scripts/conf.php:51
0.1059 550952 6. Composer\Autoload\ClassLoader->loadClass() /Users/amortang/Library/Application Support/Alfred/Alfred.alfredpreferences/workflows/user.workflow.9CE45714-7860-4A74-B002-78AA58F3BC8E/scripts/conf.php:51
0.1059 551208 7. Composer\Autoload\includeFile() /Users/amortang/Library/Application Support/Alfred/Alfred.alfredpreferences/workflows/user.workflow.9CE45714-7860-4A74-B002-78AA58F3BC8E/scripts/vendor/composer/ClassLoader.php:274
0.1063 625656 8. include('/Users/amortang/Library/Application Support/Alfred/Alfred.alfredpreferences/workflows/user.workflow.9CE45714-7860-4A74-B002-78AA58F3BC8E/scripts/vendor/rodneyrehm/plist/classes/CFPropertyList/CFPropertyList.php') /Users/amortang/Library/Application Support/Alfred/Alfred.alfredpreferences/workflows/user.workflow.9CE45714-7860-4A74-B002-78AA58F3BC8E/scripts/vendor/composer/ClassLoader.php:382


Warning: Invalid argument supplied for foreach() in /Users/amortang/Library/Application Support/Alfred/Alfred.alfredpreferences/workflows/user.workflow.9CE45714-7860-4A74-B002-78AA58F3BC8E/scripts/conf.php on line 107

Call Stack:
0.0002 395432 1. {main}() /Users/amortang/Library/Application Support/Alfred/Alfred.alfredpreferences/workflows/user.workflow.9CE45714-7860-4A74-B002-78AA58F3BC8E/cdocadd.php:0
0.0008 443448 2. require_once('/Users/amortang/Library/Application Support/Alfred/Alfred.alfredpreferences/workflows/user.workflow.9CE45714-7860-4A74-B002-78AA58F3BC8E/scripts/conf.php') /Users/amortang/Library/Application Support/Alfred/Alfred.alfredpreferences/workflows/user.workflow.9CE45714-7860-4A74-B002-78AA58F3BC8E/cdocadd.php:4
0.0017 549832 3. CFPropertyList\DevDocsConf->__construct() /Users/amortang/Library/Application Support/Alfred/Alfred.alfredpreferences/workflows/user.workflow.9CE45714-7860-4A74-B002-78AA58F3BC8E/scripts/conf.php:253
0.1118 916104 4. CFPropertyList\DevDocsConf->setDocumentations() /Users/amortang/Library/Application Support/Alfred/Alfred.alfredpreferences/workflows/user.workflow.9CE45714-7860-4A74-B002-78AA58F3BC8E/scripts/conf.php:41

这是因为7.4的php的数组不支持用大括号寻址了

根据php的报错修改一下源码的对应源码,可以用了:

编写workflow

类型

我们右键可以发现,Alfred支持的东西太多了,比如打开文件、弹个通知、打开浏览器等等

这里面有一些东西是用来控制执行流程之类的东西的,但是最核心的东西其实还是运行脚本,脚本里写的才是我们最核心的操作,你会发现有两种脚本运行:Run Script和Script Filter

简单来讲,想让一个脚本后台自己的去跑一个脚本,没有反馈,这种用run script,例如:
211300_QQ20220423-211238-HD

如果想通过一个脚本进行相应操作,不用回车,直接得到单个或多个结果,则需要Script Filter,例如:
211427_QQ20220423-211408-HD

写一个Run Script

我这个电脑的AntSword有个bug,没法退出,每次都得kill进程才能退出,所以我们就以这个为需求来写一个kill蚁剑进程的东西
新建workflow选空白即可,他也给我们提供了一些流程模板

对workflow写一些基本信息

添加一个keywords,用klat来触发,并选择不需要参数:

后面跟上一个Run Script,不用输入信息,执行固定的语句,语言选择/bin/bash

ps -ef | grep AntSword | grep -v grep | awk '{print $2}' | xargs kill -9


效果如下(蚁剑被kill掉退出了):
212403_QQ20220423-212342-HD
当然这个workflow就比较简单(但是也达到了提升工作效率的目的,这就是Alfred的初衷),其他复杂的功能大家自行探索吧,方法就是这样的。

写一个Script Filter

这里我们就来简单写一个货币转换的workflow吧,可以在我的github下载这个workflow

使用方法可以看github的说明,转100美元到欧元效果如下:

整个项目就一个script filter,将用户输入传给了run.py这个python文件:

在看具体文件代码之前,我们需要先来看Alfred的官方文档

这个文档告诉我们,想要使用script filter让结果显示出来,脚本的输出是有固定的json格式的,例如:

{"items": [
{
"uid": "desktop",
"type": "file",
"title": "Desktop",
"subtitle": "~/Desktop",
"arg": "~/Desktop",
"autocomplete": "Desktop",
"icon": {
"type": "fileicon",
"path": "~/Desktop"
}
}
]}

items是一个数组,里面的每一个元素是一个对象,一个对象就是一个输出结果,具体的参数的意思大家把上面文档读一读就明白了。

接着我们就来写转换货币的具体代码,主要的思路就是获取用户的输入,然后判断是否合法,如果符合要求,就去https://api.getgeoapi.com/v2/currency/convert这个货币兑换的api进行货币转换。最后的输出一定是要符合它要求的json格式,所以使用了json.dumps

import requests
import re
import os
import sys
import warnings
import json


warnings.filterwarnings('ignore')

def mysplit(s):
if not re.match(r"^[\d.]+[a-zA-Z]+$", s):
sys.exit(0)
cnt = 0
while cnt < len(s):
if s[cnt].isalpha():
break
cnt += 1
return [s[:cnt], s[cnt:]]


if len(sys.argv) < 2 or not re.match(r"^[\d.]+[a-zA-Z]+\ [a-zA-Z]+$", sys.argv[1]):
sys.exit(0)

api = os.getenv('api')
amonut_from = sys.argv[1].split(' ')[0]
to = sys.argv[1].split(' ')[1]
amonut_from_split = mysplit(amonut_from)

baseurl = "https://api.getgeoapi.com/v2/currency/convert"
url = "%s?api_key=%s&from=%s&to=%s&amount=%s&format=json" % (baseurl, api, amonut_from_split[1], to, amonut_from_split[0])
r = requests.get(url)
res = r.json()
if res['status'] != 'success' :
print(json.dumps({"items":[{"title": "Error", "subtitle" : "something wrong", "arg" : "please check your input"}]}))
sys.exit(0)

result = {}
try:
result = res['rates'][list(res['rates'].keys())[0]]
except:
print(json.dumps({"items":[{"title": "Error", "subtitle" : "something wrong", "arg" : "please check your input"}]}))
sys.exit(0)


items = {"items": [
{
"subtitle": "currency name",
"title": result['currency_name'],
"arg": result['currency_name']
},
{
"subtitle": "rate",
"title": result['rate'],
"arg": result['rate']
},
{
"subtitle": "Total value of currency after conversion",
"title": result['rate_for_amount'],
"arg": result['rate_for_amount']
}]
}
print(json.dumps(items))

但是这里面我们使用了一个api接口,这个api接口需要有API Key才可以,我们不能把这个API Key写死在代码里,因为我们希望能让用户自己去注册去申请它自己的API Key,而又不用编写源代码文件就可以把API Key导入进去,这时我们可以设置Alfred当前workflow的环境变量。点击这个[x]

左边是项目的描述,右边就是环境变量的键和值,勾上Do not export的话导出时就不会把值给导出了

这样在代码里就可以通过获取环境变量的方法os.getenv('api')来取到了。
在share中可以导出workflow,相当于生成release版本,这里可以对项目信息进行一些配置之类的,然后就可以分享给你的小伙伴了,或者分享到Alfred论坛

Author: Y1ng
Link: https://www.gem-love.com/2022/04/23/Alfred-4-MacOS效率提升大杀器-下篇/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.
【腾讯云】热门云产品首单特惠秒杀,2核2G云服务器45元/年    【腾讯云】境外1核2G服务器低至2折,半价续费券限量免费领取!