SwitchHosts! 支持 Alfred 小记
很早就有人建议让 SwitchHosts 支持 Alfred ,我也曾多次想过开发这个功能,但拖延症很严重,一直没有动手😅。最近注意到 SwitchHosts 在 GitHub 上已经有超过 2000 个 star,开心的同时也觉得压力开始大了起来,于是抽空认真梳理了一遍代码,做了若干改造,修复了若干遗留问题(当然,还有一些仍待处理),最后,添加了对 Alfred workflow 的支持。
当然,由于 Alfred 仅支持 macOS,这个功能也只支持 macOS。
使用方法:
- 下载 SwitchHosts 最新版本(v3.3.0 或更新版本)
- 下载对应的 workflow 文件并安装
- 在 Alfred 界面输入关键词
swh
,即可列出当前 hosts 方案列表,并可直接在下拉菜单中进行切换
效果如下:
下面记录一下工作原理以及开发说明。
工作原理
工作原理非常简单:SwitchHosts 启动时,开启一个 HTTP 服务,提供了 list
以及 toggle
两个接口,顾名思义,list
就是列出所有可用的 hosts 方案,toggle
则是切换指定方案。接下来,Alfred 则根据用户指令,请求对应的接口。如下图所示:
HTTP 服务使用了 express.js 来实现(源码),随 app 启动,监听 50761 端口。启动 app 后,你可以在浏览器中访问 http://127.0.0.1:50761 ,如果能正常打开页面,并看到“Hello SwitchHosts”的字样,表示 HTTP 服务已正常启动。
list
接口(源码)的访问地址为 http://127.0.0.1:50761/api/list ,返回一个 JSON ,格式形如:
{
"success": true,
"data": [
{
"id": "1490959856569-442720",
"title": "default",
"content": "# ...",
"on": true,
"where": "local",
"url": "",
"last_refresh": null,
"refresh_interval": 0,
"include": []
},
{
"id": "1490959856569-329205",
"title": "my Tests",
"content": "# ..",
"on": true,
"where": "local",
"url": "",
"last_refresh": null,
"refresh_interval": 0,
"include": []
},
...
注意其中每个 hosts 方案都有一个 id
,这个 id
将会在下面的 toggle
接口中使用。
toggle
接口(源码)的访问地址为 http://127.0.0.1:50761/api/toggle?id={id} ,它接受一个 id
参数,查询对应的 hosts,并进行切换。
目前 SwitchHosts 只提供了 Alfred 支持,不过有了 list
和 toggle
这两个接口,理论上用户可以为任何第三方工具开发 SwitchHosts 的支持。
代码实现
接下来就是 Alfred 的部分了,源码在这里,使用的是 Python 作为开发语言,参考了这个教程。
其中生成列表的代码如下:
# -*- coding: utf-8 -*-
import sys
# the workflow package below is download from:
# https://github.com/deanishe/alfred-workflow/releases
from workflow import Workflow, ICON_WEB, web
def get_subtitle(item):
content = item.get('content', '')
return content.partition('\n')[0].strip()
def main(wf):
url = 'http://127.0.0.1:50761/api/list'
r = web.get(url)
# throw an error if request failed
# Workflow will catch this and show it to the user
r.raise_for_status()
# Parse the JSON returned by pinboard and extract the posts
result = r.json()
items = result['data']
# Loop through the returned posts and add an item for each to
# the list of results for Alfred
for item in items:
on = item.get('on', False)
wf.add_item(title=item['title'],
subtitle=get_subtitle(item),
arg=item['id'],
valid=True,
icon='on.png' if on else 'off.png')
# Send the results to Alfred as XML
wf.send_feedback()
if __name__ == '__main__':
my_wf = Workflow()
sys.exit(my_wf.run(main))
用到的 python workflow 模块可以从这儿下载。
用户选中切换的脚本则非常简单,传入 id 后,访问对应的 toggle
接口即可,Alfred 中的 workflow 脚本只有一行:
curl 'http://127.0.0.1:50761/api/toggle?id={query}'
下载
最后,再贴一下 Alfred workflow 的下载地址,使用过程中有任何问题,欢迎给我提 issue 。
后续
【2022-06-08 更新】
macOS 12.3 中移除了 Python 2,导致原来的 Alfred workflow 失效(参见 #692),于是用 JavaScript 重写了这个 workflow,版本号升级为 1.3,下载地址不变。
评论:
在WIN10中以管理员身份打开,依然弹出错误,没有权限,提示用管理员身份打开软件。
可能是电脑上的安全软件引起的,比如360安全卫士、卡巴斯基等。试试将 SwitchHosts! 添加到安全软件的受信任组,并在文件监听里设置 hosts 为排除项。参见 #158 。
我的也出现这个问题, 未安装安全软件,win10防火墙已添加信任软件
有了这个,是不是就不用启动软件来切换hosts啦?
Switchhosts! 还是要运行,不过切换时不用通过它,它一直在后台运行就行。
有点尴尬的地方是,如果我想关闭一个开启一个,这个好像没有办法那样操作,还是要到界面上进行设置
嗯,要操作两次,或者在选项中设置为单选模式。
[…] 的 macOS 版本里,还支持 Alfred 快速调用。你可以在作者网站主页了解更多软件支持 Alfred 背后的开发故事。在一键切换、Hosts […]
[…] 的 macOS 版本里,还支持 Alfred 快速调用。你可以在作者网站主页了解更多软件支持 Alfred 背后的开发故事。在一键切换、Hosts […]